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 get_bifurcation_triple_point(p1x, p1d, p2x, p2d, p3x, p3d):
    '''
    Get coordinates and derivatives of triple point between p1, p2 and p3 with derivatives.
    :param p1x..p3d: Point coordinates and derivatives, numbered anticlockwise around triple point.
    All derivatives point away from triple point.
    Returned d1 points from triple point to p2, d2 points from triple point to p3.
    :return: x, d1, d2
    '''
    trx1 = interpolateCubicHermite(p1x, mult(p1d, -2.0), p2x, mult(p2d, 2.0), 0.5)
    trx2 = interpolateCubicHermite(p2x, mult(p2d, -2.0), p3x, mult(p3d, 2.0), 0.5)
    trx3 = interpolateCubicHermite(p3x, mult(p3d, -2.0), p1x, mult(p1d, 2.0), 0.5)
    trx = [ (trx1[c] + trx2[c] + trx3[c])/3.0 for c in range(3) ]
    td1 = interpolateLagrangeHermiteDerivative(trx, p1x, p1d, 0.0)
    td2 = interpolateLagrangeHermiteDerivative(trx, p2x, p2d, 0.0)
    td3 = interpolateLagrangeHermiteDerivative(trx, p3x, p3d, 0.0)
    n12 = cross(td1, td2)
    n23 = cross(td2, td3)
    n31 = cross(td3, td1)
    norm = normalize([ (n12[c] + n23[c] + n31[c]) for c in range(3) ])
    sd1 = smoothCubicHermiteDerivativesLine([ trx, p1x ], [ normalize(cross(norm, cross(td1, norm))), p1d ], fixStartDirection=True, fixEndDerivative=True)[0]
    sd2 = smoothCubicHermiteDerivativesLine([ trx, p2x ], [ normalize(cross(norm, cross(td2, norm))), p2d ], fixStartDirection=True, fixEndDerivative=True)[0]
    sd3 = smoothCubicHermiteDerivativesLine([ trx, p3x ], [ normalize(cross(norm, cross(td3, norm))), p3d ], fixStartDirection=True, fixEndDerivative=True)[0]
    trd1 = mult(sub(sd2, add(sd3, sd1)), 0.5)
    trd2 = mult(sub(sd3, add(sd1, sd2)), 0.5)
    return trx, trd1, trd2
 def _createNodeTree(self, generation, x1, d1, r, forkNormal):
     '''
     Create node with specified x1, d1, r and recursively add two child nodes until generationCount.
     :param forkNormal: Unit direction normal to d1 and child branches.
     :return: Top node of tree.
     '''
     node = TreeNode(x1, d1, r)
     if generation < self._generationCount:
         branchLength = magnitude(d1) * self._branchLengthRatio
         main = mult(d1, self._cosForkAngle * self._branchLengthRatio)
         side = mult(cross(forkNormal, d1),
                     self._sinForkAngle * self._branchLengthRatio)
         branch1d1 = add(main, side)
         branch2d1 = sub(main, side)
         if self._branchArcRadians > 0.0:
             arcr = branchLength / self._branchArcRadians
             arc2 = mult(branch1d1, arcr / branchLength)
             arc1 = cross(arc2, forkNormal)
             arcc = sub(x1, arc1)
             branch1x2 = add(
                 arcc,
                 add(mult(arc1, self._cosBranchArc),
                     mult(arc2, self._sinBranchArc)))
             branch1d2 = mult(
                 add(mult(arc1, -self._sinBranchArc),
                     mult(arc2, self._cosBranchArc)), branchLength / arcr)
             arc2 = mult(branch2d1, arcr / branchLength)
             arc1 = cross(forkNormal, arc2)
             arcc = sub(x1, arc1)
             branch2x2 = add(
                 arcc,
                 add(mult(arc1, self._cosBranchArc),
                     mult(arc2, self._sinBranchArc)))
             branch2d2 = mult(
                 add(mult(arc1, -self._sinBranchArc),
                     mult(arc2, self._cosBranchArc)), branchLength / arcr)
         else:
             branch1x2 = add(x1, branch1d1)
             branch1d2 = branch1d1
             branch2x2 = add(x1, branch2d1)
             branch2d2 = branch2d1
         branch1Normal = normalize(cross(forkNormal, branch1d2))
         branch2Normal = normalize(cross(forkNormal, branch2d2))
         forkRadius = r * self._forkRadiusRatio
         node.addChild(
             self._createNodeTree(generation + 1, branch1x2, branch1d2,
                                  forkRadius * self._branchRadiusRatio,
                                  branch1Normal), branch1d1, forkRadius)
         node.addChild(
             self._createNodeTree(generation + 1, branch2x2, branch2d2,
                                  forkRadius * self._branchRadiusRatio,
                                  branch2Normal), branch2d1, forkRadius)
     return node
 def mouseMoveEvent(self, event):
     if 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)
Example #5
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)
Example #6
0
def calculatePlaneNormal(pt1, pt2, pt3):
    dir_1 = sub(pt2, pt1)
    dir_2 = sub(pt3, pt1)
    cross_vec = cross(dir_1, dir_2)
    return normalize(cross_vec)
def calculatePlaneNormal(pt1, pt2, pt3):
    dir_1 = sub(pt2, pt1)
    dir_2 = sub(pt3, pt1)
    cross_vec = cross(dir_1, dir_2)
    return normalize(cross_vec)
Example #8
0
 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)
Example #9
0
    def generateBaseMesh(cls, region, options):
        """
        Generate the base bicubic Hermite mesh.
        :param region: Zinc region to define model in. Must be empty.
        :param options: Dict containing options. See getDefaultOptions().
        :return: list of AnnotationGroup
        """
        paCount = options['Number of elements around parent']
        c1Count = options['Number of elements around child 1']
        c2Count = options['Number of elements around child 2']
        parentRadius = 0.5 * options['Parent diameter']
        parentLength = options['Parent length']
        parentLengthScaleFactor = options['Parent length scale factor']
        child1AngleRadians = math.radians(options['Child 1 angle degrees'])
        child1Radius = 0.5 * options['Child 1 diameter']
        child1Length = options['Child 1 length']
        child1LengthScaleFactor = options['Child 1 length scale factor']
        child2AngleRadians = math.radians(options['Child 2 angle degrees'])
        child2Radius = 0.5 * options['Child 2 diameter']
        child2Length = options['Child 2 length']
        child2LengthScaleFactor = options['Child 2 length scale factor']
        useCrossDerivatives = False

        # centres:
        paCentre = [0.0, 0.0, -parentLength]
        c1Centre = [
            child1Length * math.sin(child1AngleRadians), 0.0,
            child1Length * math.cos(child1AngleRadians)
        ]
        c2Centre = [
            child2Length * math.sin(child2AngleRadians), 0.0,
            child2Length * math.cos(child2AngleRadians)
        ]
        c12 = sub(c1Centre, c2Centre)

        pac1Count, pac2Count, c1c2Count = get_tube_bifurcation_connection_elements_counts(
            paCount, c1Count, c2Count)

        # parent ring
        paAxis3 = [0.0, 0.0, parentLength]
        paAxis2 = mult(normalize(cross(paAxis3, c12)), parentRadius)
        paAxis1 = mult(normalize(cross(paAxis2, paAxis3)), parentRadius)
        paStartRadians = -math.pi * (pac1Count / paCount)
        pax, pad1 = createCirclePoints(paCentre, paAxis1, paAxis2, paCount,
                                       paStartRadians)
        pad2 = [mult(paAxis3, parentLengthScaleFactor)] * paCount
        # child 1 ring
        c1Axis3 = c1Centre
        c1Axis2 = mult(normalize(cross(c1Axis3, c12)), child1Radius)
        c1Axis1 = mult(normalize(cross(c1Axis2, c1Axis3)), child1Radius)
        c1StartRadians = -math.pi * (pac1Count / c1Count)
        c1x, c1d1 = createCirclePoints(c1Centre, c1Axis1, c1Axis2, c1Count,
                                       c1StartRadians)
        c1d2 = [mult(c1Axis3, child1LengthScaleFactor)] * c1Count
        # child 2 ring
        c2Axis3 = c2Centre
        c2Axis2 = mult(normalize(cross(c2Axis3, c12)), child2Radius)
        c2Axis1 = mult(normalize(cross(c2Axis2, c2Axis3)), child2Radius)
        c2StartRadians = -math.pi * (c1c2Count / c2Count)
        c2x, c2d1 = createCirclePoints(c2Centre, c2Axis1, c2Axis2, c2Count,
                                       c2StartRadians)
        c2d2 = [mult(c2Axis3, child2LengthScaleFactor)] * c2Count

        rox, rod1, rod2, cox, cod1, cod2, paStartIndex, c1StartIndex, c2StartIndex = \
            make_tube_bifurcation_points(paCentre, pax, pad2, c1Centre, c1x, c1d2, c2Centre, c2x, c2d2)

        fm = region.getFieldmodule()
        coordinates = findOrCreateFieldCoordinates(fm)
        cache = fm.createFieldcache()

        nodes = fm.findNodesetByFieldDomainType(Field.DOMAIN_TYPE_NODES)

        ##############
        # Create nodes
        ##############

        nodeIdentifier = 1

        nodetemplate = nodes.createNodetemplate()
        nodetemplate.defineField(coordinates)
        nodetemplate.setValueNumberOfVersions(coordinates, -1,
                                              Node.VALUE_LABEL_VALUE, 1)
        nodetemplate.setValueNumberOfVersions(coordinates, -1,
                                              Node.VALUE_LABEL_D_DS1, 1)
        nodetemplate.setValueNumberOfVersions(coordinates, -1,
                                              Node.VALUE_LABEL_D_DS2, 1)
        paNodeId = []
        for n in range(paCount):
            node = nodes.createNode(nodeIdentifier, nodetemplate)
            cache.setNode(node)
            coordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_VALUE, 1,
                                          pax[n])
            coordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_D_DS1, 1,
                                          pad1[n])
            coordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_D_DS2, 1,
                                          pad2[n])
            paNodeId.append(nodeIdentifier)
            nodeIdentifier = nodeIdentifier + 1
        roNodeId = []
        for n in range(len(rox)):
            node = nodes.createNode(nodeIdentifier, nodetemplate)
            cache.setNode(node)
            coordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_VALUE, 1,
                                          rox[n])
            coordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_D_DS1, 1,
                                          rod1[n])
            coordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_D_DS2, 1,
                                          rod2[n])
            roNodeId.append(nodeIdentifier)
            nodeIdentifier = nodeIdentifier + 1
        coNodeId = []
        for n in range(len(cox)):
            node = nodes.createNode(nodeIdentifier, nodetemplate)
            cache.setNode(node)
            coordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_VALUE, 1,
                                          cox[n])
            coordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_D_DS1, 1,
                                          cod1[n])
            coordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_D_DS2, 1,
                                          cod2[n])
            coNodeId.append(nodeIdentifier)
            nodeIdentifier = nodeIdentifier + 1
        c1NodeId = []
        for n in range(c1Count):
            node = nodes.createNode(nodeIdentifier, nodetemplate)
            cache.setNode(node)
            coordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_VALUE, 1,
                                          c1x[n])
            coordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_D_DS1, 1,
                                          c1d1[n])
            coordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_D_DS2, 1,
                                          c1d2[n])
            c1NodeId.append(nodeIdentifier)
            nodeIdentifier = nodeIdentifier + 1
        c2NodeId = []
        for n in range(c2Count):
            node = nodes.createNode(nodeIdentifier, nodetemplate)
            cache.setNode(node)
            coordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_VALUE, 1,
                                          c2x[n])
            coordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_D_DS1, 1,
                                          c2d1[n])
            coordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_D_DS2, 1,
                                          c2d2[n])
            c2NodeId.append(nodeIdentifier)
            nodeIdentifier = nodeIdentifier + 1

        #################
        # Create elements
        #################

        elementIdentifier = 1
        elementIdentifier = make_tube_bifurcation_elements_2d(
            region, coordinates, elementIdentifier, paNodeId, paStartIndex,
            c1NodeId, c1StartIndex, c2NodeId, c2StartIndex, roNodeId, coNodeId,
            useCrossDerivatives)

        return []