1 # -*- coding: utf-8 -*-
3 # Copyright (C) 2007-2011 CEA/DEN, EDF R&D, OPEN CASCADE
5 # This library is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU Lesser General Public
7 # License as published by the Free Software Foundation; either
8 # version 2.1 of the License.
10 # This library is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 # Lesser General Public License for more details.
15 # You should have received a copy of the GNU Lesser General Public
16 # License along with this library; if not, write to the Free Software
17 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 This module is used to compute the orientation of the different parts in a
23 structural element and to build the corresponding markers (trihedrons).
28 from salome.kernel.logger import Logger
29 from salome.kernel import termcolor
30 logger = Logger("__PAL_GEOM__.structelem.orientation", color = termcolor.RED)
35 This class is used to compute the orientation of 1D elements and to build
36 the corresponding markers.
41 self._vectorYCoords = None
45 reprdict = self.__dict__.copy()
47 return '%s(%s)' % (self.__class__.__name__, reprdict)
49 def addParams(self, params):
51 Add orientation parameters. `params` is a dictionary containing one or
52 several orientation parameters. The valid parameters are:
54 * "VECT_Y": Triplet defining the local Y axis (the X axis is the
55 main direction of the 1D element).
56 * "ANGL_VRIL": Angle of rotation along the X axis to define the local
59 The parameters can be specified several times. In this case, only the
60 first "VECT_Y" is taken into account, and the values of "ANGL_VRIL"
61 are added to obtain the total rotation angle.
63 mydict = params.copy()
64 if mydict.has_key("VECT_Y"):
65 newVecCoords = mydict.pop("VECT_Y")
66 if self._vectorYCoords is None:
67 logger.debug("Setting orientation vector Y to %s" %
69 self._vectorYCoords = newVecCoords
71 logger.warning('Orientation parameter "VECT_Y" is specified '
72 'several times for the same mesh group, vector'
73 ' %s will be used' % str(self._vectorYCoords))
74 if mydict.has_key("ANGL_VRIL"):
75 newAngle = mydict.pop("ANGL_VRIL")
76 self._angle += newAngle
77 logger.debug("Adding angle %f to orientation, new angle is %f." %
78 (newAngle, self._angle))
80 logger.warning("Invalid orientation parameter(s) (ignored): %s" %
83 def _getDefaultVecYZ(self, center, vecX):
85 Get the vectors Y and Z for the default LCS, that use the main
86 direction of the 1D object as the local X axis and the global Z axis
87 to determine the local Z axis.
89 xPoint = self.geom.MakeTranslationVector(center, vecX)
90 givenVecZ = self.geom.MakeVectorDXDYDZ(0.0, 0.0, 1.0)
91 angle = self.geom.GetAngleRadians(vecX, givenVecZ)
92 if abs(angle) < 1e-7 or abs(angle - math.pi) < 1e-7:
93 logger.warning("Beam X axis is colinear to absolute Z axis. "
94 "Absolute X axis will be used to determine "
96 givenVecZ = self.geom.MakeVectorDXDYDZ(1.0, 0.0, 0.0)
97 zPoint = self.geom.MakeTranslationVector(center, givenVecZ)
98 locPlaneZX = self.geom.MakePlaneThreePnt(center, zPoint, xPoint, 1.0)
99 locY = self.geom.GetNormal(locPlaneZX)
100 yPoint = self.geom.MakeTranslationVector(center, locY)
101 locPlaneXY = self.geom.MakePlaneThreePnt(center, xPoint, yPoint, 1.0)
102 locZ = self.geom.GetNormal(locPlaneXY)
105 def buildMarker(self, geom, center, vecX):
107 Create a marker with origin `center` and X axis `vecX`. `geom` is the
108 pseudo-geompy object used to build the geometric shapes.
110 (locY, locZ) = self.getVecYZ(geom, center, vecX)
111 marker = geom.MakeMarkerPntTwoVec(center, vecX, locY)
114 def getVecYZ(self, geom, center, vecX):
116 Get the vectors Y and Z for the LCS with origin `center` and X axis
117 `vecX`. `geom` is the pseudo-geompy object used to build the geometric
123 if self._vectorYCoords is None:
124 (locY, locZ) = self._getDefaultVecYZ(center, vecX)
126 xPoint = self.geom.MakeTranslationVector(center, vecX)
127 givenLocY = self.geom.MakeVectorDXDYDZ(self._vectorYCoords[0],
128 self._vectorYCoords[1],
129 self._vectorYCoords[2])
130 angle = self.geom.GetAngleRadians(vecX, givenLocY)
131 if abs(angle) < 1e-7 or abs(angle - math.pi) < 1e-7:
132 logger.warning("Vector Y is colinear to the beam X axis, "
133 "using default LCS.")
134 (locY, locZ) = self._getDefaultVecYZ(center, vecX)
136 yPoint = self.geom.MakeTranslationVector(center, givenLocY)
137 locPlaneXY = self.geom.MakePlaneThreePnt(center, xPoint,
139 locZ = self.geom.GetNormal(locPlaneXY)
140 zPoint = self.geom.MakeTranslationVector(center, locZ)
141 locPlaneZX = self.geom.MakePlaneThreePnt(center, zPoint,
143 locY = self.geom.GetNormal(locPlaneZX)
145 if self._angle != 0.0:
146 angleRad = math.radians(self._angle)
147 locY = self.geom.Rotate(locY, vecX, angleRad)
148 locZ = self.geom.Rotate(locZ, vecX, angleRad)
155 This class is used to compute the orientation of 2D elements and to build
156 the corresponding markers. Angles `alpha` and `beta` are used to determine
157 the local coordinate system for the 2D element. If `vect` is not
158 :const:`None`, it is used instead of `alpha` and `beta`.
161 def __init__(self, alpha, beta, vect):
168 reprdict = self.__dict__.copy()
170 return '%s(%s)' % (self.__class__.__name__, reprdict)
172 def _buildDefaultMarker(self, center, normal, warnings = True):
174 Create the default marker, that use the normal vector of the 2D object
175 as the local Z axis and the global X axis to determine the local X
176 axis. `warnings` can be used to enable or disable the logging of
180 globalVecX = self.geom.MakeVectorDXDYDZ(1.0, 0.0, 0.0)
181 angle = self.geom.GetAngleRadians(normal, globalVecX)
182 if abs(angle) < 1e-7 or abs(angle - math.pi) < 1e-7:
184 logger.warning("Face normal is colinear to absolute X axis. "
185 "Absolute Y axis will be used to determine "
187 globalVecY = self.geom.MakeVectorDXDYDZ(0.0, 1.0, 0.0)
188 marker = self._buildMarkerRefVecX(center, normal, globalVecY)
190 marker = self._buildMarkerRefVecX(center, normal, globalVecX)
193 def _buildMarkerRefVecX(self, center, normal, refVecX):
195 Create a marker using `normal` as Z axis and `refVecX` to determine
198 xPoint = self.geom.MakeTranslationVector(center, refVecX)
199 zPoint = self.geom.MakeTranslationVector(center, normal)
200 locPlaneZX = self.geom.MakePlaneThreePnt(center, zPoint, xPoint, 1.0)
201 locY = self.geom.GetNormal(locPlaneZX)
202 yPoint = self.geom.MakeTranslationVector(center, locY)
203 locPlaneYZ = self.geom.MakePlaneThreePnt(center, yPoint, zPoint, 1.0)
204 locX = self.geom.GetNormal(locPlaneYZ)
205 marker = self.geom.MakeMarkerPntTwoVec(center, locX, locY)
208 def buildMarker(self, geom, center, normal, warnings = True):
210 Create a marker with origin `center` and `normal` as Z axis. The other
211 axes are computed using the parameters alpha and beta of the
212 Orientation2D instance. `geom` is the pseudo-geompy object used to
213 build the geometric shapes. `warnings` can be used to enable or
214 disable the logging of warning messages.
219 if self._vect is not None:
220 # Using vector parameter
221 if abs(self._vect[0]) <= 1e-7 and abs(self._vect[1]) <= 1e-7 and \
222 abs(self._vect[2]) <= 1e-7:
224 logger.warning("Vector too small: %s, using default LCS" %
227 refVecX = self.geom.MakeVectorDXDYDZ(self._vect[0],
230 elif self._alpha is not None and self._beta is not None:
231 # Using alpha and beta angles
232 alphaRad = math.radians(self._alpha)
233 betaRad = math.radians(self._beta)
234 if abs(alphaRad) <= 1e-7 and abs(betaRad) <= 1e-7:
236 logger.warning("Angles too small: (%g, %g), using "
237 "default LCS" % (self._alpha, self._beta))
239 # rotate global CS with angles alpha and beta
240 refVecX = self.geom.MakeVectorDXDYDZ(1.0, 0.0, 0.0)
241 refVecY = self.geom.MakeVectorDXDYDZ(0.0, 1.0, 0.0)
242 globalVecZ = self.geom.MakeVectorDXDYDZ(0.0, 0.0, 1.0)
243 if abs(alphaRad) > 1e-7:
244 refVecX = self.geom.Rotate(refVecX, globalVecZ, alphaRad)
245 refVecY = self.geom.Rotate(refVecY, globalVecZ, alphaRad)
246 if abs(betaRad) > 1e-7:
247 refVecX = self.geom.Rotate(refVecX, refVecY, betaRad)
249 if refVecX is not None:
250 # build local coordinate system
251 angle = self.geom.GetAngleRadians(normal, refVecX)
252 if abs(angle) < 1e-7 or abs(angle - math.pi) < 1e-7:
254 logger.warning("Face normal is colinear to the reference "
255 "X axis, using default LCS.")
257 marker = self._buildMarkerRefVecX(center, normal, refVecX)
260 marker = self._buildDefaultMarker(center, normal, warnings)