Пример #1
0
def get_curve_circle_points(x1, xd1, x2, xd2, r1, rd1, r2, rd2, xi, dmag, side, elementsCountAround):
    '''
    :param dmag: Magnitude of derivative on curve.
    :param side: Vector in side direction of first node around.
    Need not be unit or exactly normal to curve at xi.
    :return: x[], d1[] around, d2[] along
    '''
    cx = interpolateCubicHermite(x1, xd1, x2, xd2, xi)
    cxd = interpolateCubicHermiteDerivative(x1, xd1, x2, xd2, xi)
    mag_cxd = magnitude(cxd)
    cxd2 = interpolateCubicHermiteSecondDerivative(x1, xd1, x2, xd2, xi)
    mag_cxd2 = magnitude(cxd2)
    r = interpolateCubicHermite([ r1 ], [ rd1 ], [ r2 ], [ rd2 ], xi)[0]
    rd = interpolateCubicHermiteDerivative([ r1 ], [ rd1 ], [ r2 ], [ rd2 ], xi)[0]
    axis1 = normalize(cxd)
    axis3 = normalize(cross(axis1, side))
    axis2 = cross(axis3, axis1)
    x, d1 = createCirclePoints(cx, mult(axis2, r), mult(axis3, r), elementsCountAround)
    curvatureVector = mult(cxd2, 1.0/(mag_cxd*mag_cxd))
    d2 = []
    radialGrowth = rd/(mag_cxd*r)
    for e in range(elementsCountAround):
        radialVector = sub(x[e], cx)
        dmagFinal = dmag*(1.0 - dot(radialVector, curvatureVector))
        # add curvature and radius change components:
        d2.append(add(mult(cxd, dmagFinal/mag_cxd), mult(radialVector, dmagFinal*radialGrowth)))
    return x, d1, d2
 def _stdViewsButtonClicked(self):
     sceneviewer = self._ui.alignmentsceneviewerwidget.getSceneviewer()
     if sceneviewer is not None:
         result, eyePosition, lookatPosition, upVector = sceneviewer.getLookatParameters(
         )
         upVector = normalize(upVector)
         viewVector = sub(lookatPosition, eyePosition)
         viewDistance = magnitude(viewVector)
         viewVector = normalize(viewVector)
         viewX = dot(viewVector, [1.0, 0.0, 0.0])
         viewY = dot(viewVector, [0.0, 1.0, 0.0])
         viewZ = dot(viewVector, [0.0, 0.0, 1.0])
         upX = dot(upVector, [1.0, 0.0, 0.0])
         upY = dot(upVector, [0.0, 1.0, 0.0])
         upZ = dot(upVector, [0.0, 0.0, 1.0])
         if (viewZ < -0.999) and (upY > 0.999):
             # XY -> XZ
             viewVector = [0.0, 1.0, 0.0]
             upVector = [0.0, 0.0, 1.0]
         elif (viewY > 0.999) and (upZ > 0.999):
             # XZ -> YZ
             viewVector = [-1.0, 0.0, 0.0]
             upVector = [0.0, 0.0, 1.0]
         else:
             # XY
             viewVector = [0.0, 0.0, -1.0]
             upVector = [0.0, 1.0, 0.0]
         eyePosition = sub(lookatPosition, mult(viewVector, viewDistance))
         sceneviewer.setLookatParametersNonSkew(eyePosition, lookatPosition,
                                                upVector)
Пример #3
0
 def mouseMoveEvent(self, event):
     if self._model.isStateAlign() and self._alignKeyPressed and (
             self._lastMousePos is not None):
         pos = [event.x(), event.y()]
         delta = [
             pos[0] - self._lastMousePos[0], pos[1] - self._lastMousePos[1]
         ]
         result, eye = self._sceneviewer.getEyePosition()
         result, lookat = self._sceneviewer.getLookatPosition()
         result, up = self._sceneviewer.getUpVector()
         lookatToEye = vectorops.sub(eye, lookat)
         eyeDistance = vectorops.magnitude(lookatToEye)
         front = vectorops.div(lookatToEye, eyeDistance)
         right = vectorops.cross(up, front)
         if self._active_button == QtCore.Qt.LeftButton:
             mag = vectorops.magnitude(delta)
             prop = vectorops.div(delta, mag)
             axis = vectorops.add(vectorops.mult(up, prop[0]),
                                  vectorops.mult(right, prop[1]))
             angle = mag * 0.002
             self._model.rotateModel(axis, angle)
         elif self._active_button == QtCore.Qt.MiddleButton:
             result, l, r, b, t, near, far = self._sceneviewer.getViewingVolume(
             )
             viewportWidth = self.width()
             viewportHeight = self.height()
             if viewportWidth > viewportHeight:
                 eyeScale = (t - b) / viewportHeight
             else:
                 eyeScale = (r - l) / viewportWidth
             offset = vectorops.add(
                 vectorops.mult(right, eyeScale * delta[0]),
                 vectorops.mult(up, -eyeScale * delta[1]))
             self._model.offsetModel(offset)
         elif self._active_button == QtCore.Qt.RightButton:
             factor = 1.0 + delta[1] * 0.0005
             if factor < 0.9:
                 factor = 0.9
             self._model.scaleModel(factor)
         self._lastMousePos = pos
     else:
         super(AlignmentSceneviewerWidget, self).mouseMoveEvent(event)
 def mouse_move_event(self, event):
     if self._lastMousePos is not None:
         pixel_scale = self._scene_viewer.get_pixel_scale()
         pos = [event.x() * pixel_scale, event.y() * pixel_scale]
         delta = [pos[0] - self._lastMousePos[0], pos[1] - self._lastMousePos[1]]
         mag = vectorops.magnitude(delta)
         if mag <= 0.0:
             return
         result, eye = self._zinc_sceneviewer.getEyePosition()
         result, lookat = self._zinc_sceneviewer.getLookatPosition()
         result, up = self._zinc_sceneviewer.getUpVector()
         lookatToEye = vectorops.sub(eye, lookat)
         eyeDistance = vectorops.magnitude(lookatToEye)
         front = vectorops.div(lookatToEye, eyeDistance)
         right = vectorops.cross(up, front)
         viewportWidth = self._scene_viewer.width()
         viewportHeight = self._scene_viewer.height()
         if self._active_button == QtCore.Qt.LeftButton:
             prop = vectorops.div(delta, mag)
             axis = vectorops.add(vectorops.mult(up, prop[0]), vectorops.mult(right, prop[1]))
             angle = mag * 0.002
             self._model.rotateModel(axis, angle)
         elif self._active_button == QtCore.Qt.MiddleButton:
             result, l, r, b, t, near, far = self._zinc_sceneviewer.getViewingVolume()
             if viewportWidth > viewportHeight:
                 eyeScale = (t - b) / viewportHeight
             else:
                 eyeScale = (r - l) / viewportWidth
             offset = vectorops.add(vectorops.mult(right, eyeScale * delta[0]), vectorops.mult(up, -eyeScale * delta[1]))
             self._model.offsetModel(offset)
         elif self._active_button == QtCore.Qt.RightButton:
             factor = 1.0 + delta[1] * 0.0005
             if factor < 0.9:
                 factor = 0.9
             self._model.scaleModel(factor)
         self._lastMousePos = pos
Пример #5
0
 def smooth(self,
            updateDirections=False,
            maxIterations=10,
            arcLengthTolerance=1.0E-6):
     '''
     :param maxIterations: Maximum iterations before stopping if not converging.
     :param arcLengthTolerance: Ratio of difference in arc length from last iteration
     divided by current arc length under which convergence is achieved. Required to
     be met by every element edge.
     '''
     if not self._derivativeMap:
         return  # no nodes being smoothed
     componentsCount = self._field.getNumberOfComponents()
     with ChangeManager(self._fieldmodule):
         fieldcache = self._fieldmodule.createFieldcache()
         for iter in range(maxIterations + 1):
             converged = True
             for edge in self._edgesMap.values():
                 lastArcLength = edge.getLastArcLength()
                 arcLength = edge.evaluateArcLength(self._nodes,
                                                    self._field, fieldcache)
                 edge.updateLastArcLength()
                 if (math.fabs(arcLength - lastArcLength) /
                         arcLength) > arcLengthTolerance:
                     converged = False
             if converged:
                 print('Derivative smoothing: Converged after', iter,
                       'iterations.')
                 break
             elif (iter == maxIterations):
                 print('Derivative smoothing: Stopping after',
                       maxIterations, 'iterations without converging.')
                 break
             for derivativeKey, derivativeEdges in self._derivativeMap.items(
             ):
                 edgeCount = len(derivativeEdges)
                 if edgeCount > 1:
                     nodeIdentifier, nodeValueLabel, nodeVersion = derivativeKey
                     fieldcache.setNode(
                         self._nodes.findNodeByIdentifier(nodeIdentifier))
                     if updateDirections:
                         x = [0.0 for _ in range(componentsCount)]
                     else:
                         result, x = self._field.getNodeParameters(
                             fieldcache, -1, nodeValueLabel, nodeVersion,
                             componentsCount)
                     mag = 0.0
                     for derivativeEdge in derivativeEdges:
                         edge, expressionIndex, totalScaleFactor = derivativeEdge
                         arcLength = edge.getArcLength()
                         if updateDirections:
                             delta = edge.getDelta()
                             if totalScaleFactor < 0.0:
                                 delta = [-d for d in delta]
                             for c in range(componentsCount):
                                 x[c] += delta[c] / arcLength
                         if self._scalingMode == DerivativeScalingMode.ARITHMETIC_MEAN:
                             mag += arcLength / math.fabs(totalScaleFactor)
                         else:  # self._scalingMode == DerivativeScalingMode.HARMONIC_MEAN
                             mag += math.fabs(totalScaleFactor) / arcLength
                     if self._scalingMode == DerivativeScalingMode.ARITHMETIC_MEAN:
                         mag /= edgeCount
                     else:  # self._scalingMode == DerivativeScalingMode.HARMONIC_MEAN
                         mag = edgeCount / mag
                     if (mag <= 0.0):
                         print('Node', nodeIdentifier, 'value', nodeValueLabel, 'version', nodeVersion, \
                               'has negative mag', mag)
                     x = setMagnitude(x, mag)
                     result = self._field.setNodeParameters(
                         fieldcache, -1, nodeValueLabel, nodeVersion, x)
             for derivativeKey, derivativeEdges in self._derivativeMap.items(
             ):
                 edgeCount = len(derivativeEdges)
                 if edgeCount == 1:
                     # boundary smoothing over single edge
                     nodeIdentifier, nodeValueLabel, nodeVersion = derivativeKey
                     edge, expressionIndex, totalScaleFactor = derivativeEdges[
                         0]
                     # re-evaluate arc length so parameters are up-to-date for other end
                     arcLength = edge.evaluateArcLength(
                         self._nodes, self._field, fieldcache)
                     fieldcache.setNode(
                         self._nodes.findNodeByIdentifier(nodeIdentifier)
                     )  # since changed by evaluateArcLength
                     otherExpressionIndex = 3 if (expressionIndex
                                                  == 1) else 1
                     otherd = edge.getParameter(otherExpressionIndex)
                     if updateDirections:
                         thisx = edge.getParameter(expressionIndex - 1)
                         otherx = edge.getParameter(otherExpressionIndex -
                                                    1)
                         bothEndsOnBoundary = False
                         otherExpression = edge.getExpression(
                             otherExpressionIndex)
                         if len(otherExpression) == 1:
                             otherNodeIdentifier, otherValueLabel, otherNodeVersion, otherTotalScaleFactor = otherExpression[
                                 0]
                             otherDerivativeKey = (otherNodeIdentifier,
                                                   otherValueLabel,
                                                   otherNodeVersion)
                             otherDerivativeEdges = self._derivativeMap.get(
                                 otherDerivativeKey)
                             bothEndsOnBoundary = (
                                 otherDerivativeEdges
                                 is not None) and (len(otherDerivativeEdges)
                                                   == 1)
                         if bothEndsOnBoundary:
                             if expressionIndex == 1:
                                 x = [(otherx[c] - thisx[c])
                                      for c in range(componentsCount)]
                             else:
                                 x = [(thisx[c] - otherx[c])
                                      for c in range(componentsCount)]
                         else:
                             if expressionIndex == 1:
                                 x = interpolateLagrangeHermiteDerivative(
                                     thisx, otherx, otherd, 0.0)
                             else:
                                 x = interpolateHermiteLagrangeDerivative(
                                     otherx, otherd, thisx, 1.0)
                         x = [d / totalScaleFactor for d in x]
                     else:
                         result, x = self._field.getNodeParameters(
                             fieldcache, -1, nodeValueLabel, nodeVersion,
                             componentsCount)
                     othermag = magnitude(otherd)
                     mag = (2.0 * arcLength -
                            othermag) / math.fabs(totalScaleFactor)
                     if (mag <= 0.0):
                         print('Derivative smoothing: Node', nodeIdentifier,
                               'label', nodeValueLabel, 'version',
                               nodeVersion, 'has negative magnitude', mag)
                     x = setMagnitude(x, mag)
                     result = self._field.setNodeParameters(
                         fieldcache, -1, nodeValueLabel, nodeVersion, x)
         # record modified nodes while ChangeManager is in effect
         if self._editNodesetGroup:
             for derivativeKey in self._derivativeMap:
                 self._editNodesetGroup.addNode(
                     (self._nodes.findNodeByIdentifier(derivativeKey[0])))
         del fieldcache
Пример #6
0
    def test_transformation(self):
        """
        Test transformation of a box scaffold with scaffold package.
        """
        scaffoldPackage = ScaffoldPackage(MeshType_3d_box1)

        tmpScale = scaffoldPackage.getScale()
        TOL = 1.0E-7
        FINETOL = 1.0E-12
        assertAlmostEqualList(self, tmpScale, [ 1.0, 1.0, 1.0 ], delta=FINETOL)
        newScale = [ 2.0, 1.5, 0.5 ]
        scaffoldPackage.setScale(newScale)
        tmpScale = scaffoldPackage.getScale()
        assertAlmostEqualList(self, tmpScale, newScale, delta=FINETOL)

        tmpRotation = scaffoldPackage.getRotation()
        assertAlmostEqualList(self, tmpRotation, [ 0.0, 0.0, 0.0 ], delta=FINETOL)
        newRotation = [ 30.0, -10.0, 90.0 ]
        scaffoldPackage.setRotation(newRotation)
        tmpRotation = scaffoldPackage.getRotation()
        assertAlmostEqualList(self, tmpRotation, newRotation, delta=FINETOL)

        tmpTranslation = scaffoldPackage.getTranslation()
        assertAlmostEqualList(self, tmpTranslation, [ 0.0, 0.0, 0.0 ], delta=FINETOL)
        newTranslation = [ 0.5, 1.2, -0.1 ]
        scaffoldPackage.setTranslation(newTranslation)
        tmpTranslation = scaffoldPackage.getTranslation()
        assertAlmostEqualList(self, tmpTranslation, newTranslation, delta=FINETOL)

        context = Context("Test")
        region = context.getDefaultRegion()
        self.assertTrue(region.isValid())

        scaffoldPackage.generate(region)

        fieldmodule = region.getFieldmodule()
        nodes = fieldmodule.findNodesetByFieldDomainType(Field.DOMAIN_TYPE_NODES)
        self.assertEqual(8, nodes.getSize())

        coordinates = fieldmodule.findFieldByName("coordinates").castFiniteElement()
        self.assertTrue(coordinates.isValid())
        minimums, maximums = evaluateFieldNodesetRange(coordinates, nodes)
        assertAlmostEqualList(self, minimums, [  2.744244002293470e-01,  6.367511648575830e-01, -1.000000000000000e-01 ], delta=TOL)
        assertAlmostEqualList(self, maximums, [  2.455737063904887e+00,  2.184807753012208e+00,  1.724507984852172e+00 ], delta=TOL)

        node = nodes.findNodeByIdentifier(8)
        self.assertTrue(node.isValid())
        fieldcache = fieldmodule.createFieldcache()
        fieldcache.setNode(node)
        result, x = coordinates.getNodeParameters(fieldcache, -1, Node.VALUE_LABEL_VALUE, 1, 3)
        self.assertEqual(RESULT_OK, result)
        assertAlmostEqualList(self, x , [  2.230161464134234e+00,  1.621558917869791e+00,  1.724507984852172e+00 ], delta=TOL)
        # derivative magnitudes must also equal scale
        result, d1 = coordinates.getNodeParameters(fieldcache, -1, Node.VALUE_LABEL_D_DS1, 1, 3)
        self.assertEqual(RESULT_OK, result)
        assertAlmostEqualList(self, d1, [  1.705737064039425e+00,  9.848077530127952e-01,  3.472963553408093e-01 ], delta=TOL)
        self.assertAlmostEqual(newScale[0], magnitude(d1), delta=TOL)
        result, d2 = coordinates.getNodeParameters(fieldcache, -1, Node.VALUE_LABEL_D_DS2, 1, 3)
        self.assertEqual(RESULT_OK, result)
        assertAlmostEqualList(self, d2, [ -2.255755995328457e-01, -1.302361332111701e-01,  1.477211629352659e+00 ], delta=TOL)
        self.assertAlmostEqual(newScale[1], magnitude(d2), delta=TOL)
        result, d3 = coordinates.getNodeParameters(fieldcache, -1, Node.VALUE_LABEL_D_DS3, 1, 3)
        self.assertEqual(RESULT_OK, result)
        assertAlmostEqualList(self, d3, [  2.499999998128999e-01, -4.330127019169794e-01,  0.000000000000000e+00 ], delta=TOL)
        self.assertAlmostEqual(newScale[2], magnitude(d3), delta=TOL)
 def mouseMoveEvent(self, event):
     if self._editNode:
         mousePos = [event.x(), event.y()]
         nodeset = self._editNode.getNodeset()
         fieldmodule = nodeset.getFieldmodule()
         with ChangeManager(fieldmodule):
             meshEditsNodeset = self._model.getOrCreateMeshEditsNodesetGroup(
                 nodeset)
             meshEditsNodeset.addNode(self._editNode)
             editCoordinateField = coordinateField = self._editGraphics.getCoordinateField(
             )
             localScene = self._editGraphics.getScene(
             )  # need set local scene to get correct transformation
             if coordinateField.getCoordinateSystemType(
             ) != Field.COORDINATE_SYSTEM_TYPE_RECTANGULAR_CARTESIAN:
                 editCoordinateField = fieldmodule.createFieldCoordinateTransformation(
                     coordinateField)
                 editCoordinateField.setCoordinateSystemType(
                     Field.COORDINATE_SYSTEM_TYPE_RECTANGULAR_CARTESIAN)
             fieldcache = fieldmodule.createFieldcache()
             fieldcache.setNode(self._editNode)
             componentsCount = coordinateField.getNumberOfComponents()
             result, initialCoordinates = editCoordinateField.evaluateReal(
                 fieldcache, componentsCount)
             if result == RESULT_OK:
                 for c in range(componentsCount, 3):
                     initialCoordinates.append(0.0)
                 pointattr = self._editGraphics.getGraphicspointattributes()
                 editVectorField = vectorField = pointattr.getOrientationScaleField(
                 )
                 pointBaseSize = pointattr.getBaseSize(3)[1][0]
                 pointScaleFactor = pointattr.getScaleFactors(3)[1][0]
                 if editVectorField.isValid() and (vectorField.getNumberOfComponents() == componentsCount) \
                         and (pointBaseSize == 0.0) and (pointScaleFactor != 0.0):
                     if vectorField.getCoordinateSystemType(
                     ) != Field.COORDINATE_SYSTEM_TYPE_RECTANGULAR_CARTESIAN:
                         editVectorField = fieldmodule.createFieldCoordinateTransformation(
                             vectorField, coordinateField)
                         editVectorField.setCoordinateSystemType(
                             Field.
                             COORDINATE_SYSTEM_TYPE_RECTANGULAR_CARTESIAN)
                     result, initialVector = editVectorField.evaluateReal(
                         fieldcache, componentsCount)
                     for c in range(componentsCount, 3):
                         initialVector.append(0.0)
                     initialTipCoordinates = [
                         (initialCoordinates[c] +
                          initialVector[c] * pointScaleFactor)
                         for c in range(3)
                     ]
                     windowCoordinates = self.projectLocal(
                         initialTipCoordinates[0], initialTipCoordinates[1],
                         initialTipCoordinates[2], localScene)
                     finalTipCoordinates = self.unprojectLocal(
                         mousePos[0], -mousePos[1], windowCoordinates[2],
                         localScene)
                     finalVector = [
                         (finalTipCoordinates[c] - initialCoordinates[c]) /
                         pointScaleFactor for c in range(3)
                     ]
                     result = editVectorField.assignReal(
                         fieldcache, finalVector)
                 else:
                     windowCoordinates = self.projectLocal(
                         initialCoordinates[0], initialCoordinates[1],
                         initialCoordinates[2], localScene)
                     xa = self.unprojectLocal(self._lastMousePos[0],
                                              -self._lastMousePos[1],
                                              windowCoordinates[2],
                                              localScene)
                     xb = self.unprojectLocal(mousePos[0], -mousePos[1],
                                              windowCoordinates[2],
                                              localScene)
                     finalCoordinates = [
                         (initialCoordinates[c] + xb[c] - xa[c])
                         for c in range(3)
                     ]
                     result = editCoordinateField.assignReal(
                         fieldcache, finalCoordinates)
                 del editVectorField
             del editCoordinateField
             del fieldcache
         self._lastMousePos = mousePos
         event.accept()
         return
     if self._alignMode != self.AlignMode.NONE:
         mousePos = [event.x(), event.y()]
         delta = [
             mousePos[0] - self._lastMousePos[0],
             mousePos[1] - self._lastMousePos[1]
         ]
         result, eye = self._sceneviewer.getEyePosition()
         result, lookat = self._sceneviewer.getLookatPosition()
         result, up = self._sceneviewer.getUpVector()
         lookatToEye = sub(eye, lookat)
         eyeDistance = magnitude(lookatToEye)
         front = div(lookatToEye, eyeDistance)
         right = cross(up, front)
         if self._alignMode == self.AlignMode.ROTATION:
             mag = magnitude(delta)
             prop = div(delta, mag)
             axis = add(mult(up, prop[0]), mult(right, prop[1]))
             angle = mag * 0.002
             # print('delta', delta, 'axis', axis, 'angle', angle)
             self._model.interactionRotate(axis, angle)
         elif self._alignMode == self.AlignMode.SCALE:
             factor = 1.0 + delta[1] * 0.0005
             if factor < 0.9:
                 factor = 0.9
             self._model.interactionScale(factor)
         elif self._alignMode == self.AlignMode.TRANSLATION:
             result, l, r, b, t, near, far = self._sceneviewer.getViewingVolume(
             )
             viewportWidth = self.width()
             viewportHeight = self.height()
             if viewportWidth > viewportHeight:
                 eyeScale = (t - b) / viewportHeight
             else:
                 eyeScale = (r - l) / viewportWidth
             offset = add(mult(right, eyeScale * delta[0]),
                          mult(up, -eyeScale * delta[1]))
             self._model.interactionTranslate(offset)
         self._lastMousePos = mousePos
         event.accept()
         return
     else:
         super(NodeEditorSceneviewerWidget, self).mouseMoveEvent(event)