1 # -*- coding: utf-8 -*-
3 # Copyright (C) 2007-2016 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, or (at your option) any later version.
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 ## \defgroup orientation orientation
25 # This module is used to compute the orientation of the different parts in a
26 # structural element and to build the corresponding markers (trihedrons).
30 This module is used to compute the orientation of the different parts in a
31 structural element and to build the corresponding markers (trihedrons).
36 from salome.kernel.logger import Logger
37 from salome.kernel import termcolor
38 logger = Logger("salome.geom.structelem.orientation", color = termcolor.RED)
40 ## This class is used to compute the orientation of 1D elements and to build
41 # the corresponding markers.
42 # \ingroup orientation
45 This class is used to compute the orientation of 1D elements and to build
46 the corresponding markers.
51 self._vectorYCoords = None
55 reprdict = self.__dict__.copy()
57 return '%s(%s)' % (self.__class__.__name__, reprdict)
59 ## Add orientation parameters. \em params is a dictionary containing one or
60 # several orientation parameters. The valid parameters are:
61 # - "VECT_Y": Triplet defining the local Y axis (the X axis is the
62 # main direction of the 1D element).
63 # - "ANGL_VRIL": Angle of rotation along the X axis to define the local
65 # The parameters can be specified several times. In this case, only the
66 # last "VECT_Y" or "ANGL_VRIL" is taken into account.
67 def addParams(self, params):
69 Add orientation parameters. `params` is a dictionary containing one or
70 several orientation parameters. The valid parameters are:
72 * "VECT_Y": Triplet defining the local Y axis (the X axis is the
73 main direction of the 1D element).
74 * "ANGL_VRIL": Angle of rotation along the X axis to define the local
77 The parameters can be specified several times. In this case, only the
78 last "VECT_Y" or "ANGL_VRIL" is taken into account.
80 if self._vectorYCoords is not None or self._angle != 0.0:
81 logger.warning('Orientation parameters are specified several '
82 'times for the same mesh group, only the last '
83 'parameter will be used')
84 mydict = params.copy()
85 if "VECT_Y" in mydict:
86 newVecCoords = mydict.pop("VECT_Y")
87 logger.debug("Setting orientation vector Y to %s" %
89 self._vectorYCoords = newVecCoords
91 if "ANGL_VRIL" in mydict:
92 newAngle = mydict.pop("ANGL_VRIL")
93 logger.debug("Setting orientation angle to %f" % newAngle)
94 self._angle = newAngle
95 self._vectorYCoords = None
97 logger.warning("Invalid orientation parameter(s) (ignored): %s" %
99 ## Get the vectors Y and Z for the default LCS, that use the main
100 # direction of the 1D object as the local X axis and the global Z axis
101 # to determine the local Z axis.
102 def _getDefaultVecYZ(self, center, vecX):
104 Get the vectors Y and Z for the default LCS, that use the main
105 direction of the 1D object as the local X axis and the global Z axis
106 to determine the local Z axis.
108 xPoint = self.geom.MakeTranslationVector(center, vecX)
109 givenVecZ = self.geom.MakeVectorDXDYDZ(0.0, 0.0, 1.0)
110 angle = self.geom.GetAngleRadians(vecX, givenVecZ)
111 if abs(angle) < 1e-7 or abs(angle - math.pi) < 1e-7:
112 logger.warning("Beam X axis is colinear to absolute Z axis. "
113 "Absolute X axis will be used to determine "
115 givenVecZ = self.geom.MakeVectorDXDYDZ(1.0, 0.0, 0.0)
116 zPoint = self.geom.MakeTranslationVector(center, givenVecZ)
117 locPlaneZX = self.geom.MakePlaneThreePnt(center, zPoint, xPoint, 1.0)
118 locY = self.geom.GetNormal(locPlaneZX)
119 yPoint = self.geom.MakeTranslationVector(center, locY)
120 locPlaneXY = self.geom.MakePlaneThreePnt(center, xPoint, yPoint, 1.0)
121 locZ = self.geom.GetNormal(locPlaneXY)
124 ## Create a marker with origin \em center and X axis \em vecX.
125 # \em geom is the pseudo-geompy object used to build the geometric shapes.
126 def buildMarker(self, geom, center, vecX):
128 Create a marker with origin `center` and X axis `vecX`. `geom` is the
129 pseudo-geompy object used to build the geometric shapes.
131 (locY, locZ) = self.getVecYZ(geom, center, vecX)
132 marker = geom.MakeMarkerPntTwoVec(center, vecX, locY)
135 ## Get the vectors Y and Z for the LCS with origin \em center and X axis
136 # \em vecX. \em geom is the pseudo-geompy object used to build the
138 def getVecYZ(self, geom, center, vecX):
140 Get the vectors Y and Z for the LCS with origin `center` and X axis
141 `vecX`. `geom` is the pseudo-geompy object used to build the geometric
147 if self._vectorYCoords is None:
148 (locY, locZ) = self._getDefaultVecYZ(center, vecX)
150 xPoint = self.geom.MakeTranslationVector(center, vecX)
151 givenLocY = self.geom.MakeVectorDXDYDZ(self._vectorYCoords[0],
152 self._vectorYCoords[1],
153 self._vectorYCoords[2])
154 angle = self.geom.GetAngleRadians(vecX, givenLocY)
155 if abs(angle) < 1e-7 or abs(angle - math.pi) < 1e-7:
156 logger.warning("Vector Y is colinear to the beam X axis, "
157 "using default LCS.")
158 (locY, locZ) = self._getDefaultVecYZ(center, vecX)
160 yPoint = self.geom.MakeTranslationVector(center, givenLocY)
161 locPlaneXY = self.geom.MakePlaneThreePnt(center, xPoint,
163 locZ = self.geom.GetNormal(locPlaneXY)
164 zPoint = self.geom.MakeTranslationVector(center, locZ)
165 locPlaneZX = self.geom.MakePlaneThreePnt(center, zPoint,
167 locY = self.geom.GetNormal(locPlaneZX)
169 if self._angle != 0.0:
170 angleRad = math.radians(self._angle)
171 locY = self.geom.Rotate(locY, vecX, angleRad)
172 locZ = self.geom.Rotate(locZ, vecX, angleRad)
176 ## This class is used to compute the orientation of 2D elements and to build
177 # the corresponding markers. Angles \em alpha and \em beta are used to determine
178 # the local coordinate system for the 2D element. If \em vect is not
179 # \b None, it is used instead of \em alpha and \em beta.
180 # \ingroup orientation
183 This class is used to compute the orientation of 2D elements and to build
184 the corresponding markers. Angles `alpha` and `beta` are used to determine
185 the local coordinate system for the 2D element. If `vect` is not
186 :const:`None`, it is used instead of `alpha` and `beta`.
189 def __init__(self, alpha, beta, vect):
196 reprdict = self.__dict__.copy()
198 return '%s(%s)' % (self.__class__.__name__, reprdict)
200 ## Create the default marker, that use the normal vector of the 2D object
201 # as the local Z axis and the global X axis to determine the local X
202 # axis. \em warnings can be used to enable or disable the logging of
204 def _buildDefaultMarker(self, center, normal, warnings = True):
206 Create the default marker, that use the normal vector of the 2D object
207 as the local Z axis and the global X axis to determine the local X
208 axis. `warnings` can be used to enable or disable the logging of
212 globalVecX = self.geom.MakeVectorDXDYDZ(1.0, 0.0, 0.0)
213 angle = self.geom.GetAngleRadians(normal, globalVecX)
214 if abs(angle) < 1e-7 or abs(angle - math.pi) < 1e-7:
216 logger.warning("Face normal is colinear to absolute X axis. "
217 "Absolute Y axis will be used to determine "
219 globalVecY = self.geom.MakeVectorDXDYDZ(0.0, 1.0, 0.0)
220 marker = self._buildMarkerRefVecX(center, normal, globalVecY)
222 marker = self._buildMarkerRefVecX(center, normal, globalVecX)
225 ## Create a marker using \em normal as Z axis and \em refVecX
226 # to determine the X axis.
227 def _buildMarkerRefVecX(self, center, normal, refVecX):
229 Create a marker using `normal` as Z axis and `refVecX` to determine
232 xPoint = self.geom.MakeTranslationVector(center, refVecX)
233 zPoint = self.geom.MakeTranslationVector(center, normal)
234 locPlaneZX = self.geom.MakePlaneThreePnt(center, zPoint, xPoint, 1.0)
235 locY = self.geom.GetNormal(locPlaneZX)
236 yPoint = self.geom.MakeTranslationVector(center, locY)
237 locPlaneYZ = self.geom.MakePlaneThreePnt(center, yPoint, zPoint, 1.0)
238 locX = self.geom.GetNormal(locPlaneYZ)
239 marker = self.geom.MakeMarkerPntTwoVec(center, locX, locY)
242 ## Create a marker with origin \em center and \em normal as Z axis.
243 # The other axes are computed using the parameters alpha and beta of the
244 # Orientation2D instance. \em geom is the pseudo-geompy object used to
245 # build the geometric shapes. \em warnings can be used to enable or
246 # disable the logging of warning messages.
247 def buildMarker(self, geom, center, normal, warnings = True):
249 Create a marker with origin `center` and `normal` as Z axis. The other
250 axes are computed using the parameters alpha and beta of the
251 Orientation2D instance. `geom` is the pseudo-geompy object used to
252 build the geometric shapes. `warnings` can be used to enable or
253 disable the logging of warning messages.
258 if self._vect is not None:
259 # Using vector parameter
260 if abs(self._vect[0]) <= 1e-7 and abs(self._vect[1]) <= 1e-7 and \
261 abs(self._vect[2]) <= 1e-7:
263 logger.warning("Vector too small: %s, using default LCS" %
266 refVecX = self.geom.MakeVectorDXDYDZ(self._vect[0],
269 elif self._alpha is not None and self._beta is not None:
270 # Using alpha and beta angles
271 alphaRad = math.radians(self._alpha)
272 betaRad = math.radians(self._beta)
273 if abs(alphaRad) <= 1e-7 and abs(betaRad) <= 1e-7:
275 logger.warning("Angles too small: (%g, %g), using "
276 "default LCS" % (self._alpha, self._beta))
278 # rotate global CS with angles alpha and beta
279 refVecX = self.geom.MakeVectorDXDYDZ(1.0, 0.0, 0.0)
280 refVecY = self.geom.MakeVectorDXDYDZ(0.0, 1.0, 0.0)
281 globalVecZ = self.geom.MakeVectorDXDYDZ(0.0, 0.0, 1.0)
282 if abs(alphaRad) > 1e-7:
283 refVecX = self.geom.Rotate(refVecX, globalVecZ, alphaRad)
284 refVecY = self.geom.Rotate(refVecY, globalVecZ, alphaRad)
285 if abs(betaRad) > 1e-7:
286 refVecX = self.geom.Rotate(refVecX, refVecY, betaRad)
288 if refVecX is not None:
289 # build local coordinate system
290 angle = self.geom.GetAngleRadians(normal, refVecX)
291 if abs(angle) < 1e-7 or abs(angle - math.pi) < 1e-7:
293 logger.warning("Face normal is colinear to the reference "
294 "X axis, using default LCS.")
296 marker = self._buildMarkerRefVecX(center, normal, refVecX)
299 marker = self._buildDefaultMarker(center, normal, warnings)