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)
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
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
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)