Esempio n. 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
Esempio n. 2
0
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 _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)
Esempio n. 4
0
def extractImageCorners(directory, filename):
    """
    Extract the image corners from an image that is assumed to be
    a DICOM image.
    Corners are returned as:
      [bl, br, tl, tr]

    :param directory: the directory where the file given with filename exists.
    :param filename: the filename of the file to interrogate.
    :return: the corners of the image [bl, br, tl, tr]
    """
    ds = dicom.read_file(os.path.join(directory, filename))
    pixel_spacing = ds.PixelSpacing
    # delta_i = float(0.1)
    # delta_j = float(0.1)
    delta_i = float(pixel_spacing[0])
    delta_j = float(pixel_spacing[1])
    orient = [float(iop) for iop in ds.ImageOrientationPatient]
    pos = [float(ipp) for ipp in ds.ImagePositionPatient]
    rows = ds.Rows
    columns = ds.Columns
    # vectorops version
    orient_1 = orient[:3]
    orient_2 = orient[3:]
    pos_o = pos[:]
    pos = vectorops.sub(
        pos_o,
        vectorops.mult(
            vectorops.add(vectorops.mult(orient_1, 0.5),
                          vectorops.mult(orient_2, 0.5)), delta_i))

    A = [[orient[0] * delta_i, orient[3] * delta_j, 0, pos[0]],
         [orient[1] * delta_i, orient[4] * delta_j, 0, pos[1]],
         [orient[2] * delta_i, orient[5] * delta_j, 0, pos[2]], [0, 0, 0, 1]]
    b_tl = [0, 0, 0, 1]
    b_tr = [rows, 0, 0, 1]
    b_bl = [0, columns, 0, 1]
    b_br = [rows, columns, 0, 1]
    tl = vectorops.mxvectormult(A, b_tl)
    tr = vectorops.mxvectormult(A, b_tr)
    bl = vectorops.mxvectormult(A, b_bl)
    br = vectorops.mxvectormult(A, b_br)

    return [bl[:3], br[:3], tl[:3], tr[:3]]
Esempio n. 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)
 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
Esempio n. 7
0
    def _optimiseAlignment(self, pointMap):
        """
        Calculate transformation from modelCoordinates to dataMarkers
        over the markers, by scaling, translating and rotating model.
        On success, sets transformation parameters in object.
        :param pointMap: dict name -> (modelCoordinates, dataCoordinates)
        """
        assert len(pointMap) >= 3, "Align:  Only " + str(
            len(pointMap)) + " points - need at least 3"
        region = self._fitter._context.createRegion()
        fieldmodule = region.getFieldmodule()

        with ChangeManager(fieldmodule):
            modelCoordinates = fieldmodule.createFieldFiniteElement(3)
            dataCoordinates = fieldmodule.createFieldFiniteElement(3)
            nodes = fieldmodule.findNodesetByFieldDomainType(
                Field.DOMAIN_TYPE_NODES)
            nodetemplate = nodes.createNodetemplate()
            nodetemplate.defineField(modelCoordinates)
            nodetemplate.defineField(dataCoordinates)
            fieldcache = fieldmodule.createFieldcache()

            modelsum = [0.0, 0.0, 0.0]
            datasum = [0.0, 0.0, 0.0]
            modelMin = copy.deepcopy(list(pointMap.values())[0][0])
            modelMax = copy.deepcopy(list(pointMap.values())[0][0])
            dataMin = copy.deepcopy(list(pointMap.values())[0][1])
            dataMax = copy.deepcopy(list(pointMap.values())[0][1])
            for name, positions in pointMap.items():
                modelx = positions[0]
                datax = positions[1]
                modelsum = [(modelsum[c] + modelx[c]) for c in range(3)]
                datasum = [(datasum[c] + datax[c]) for c in range(3)]
                node = nodes.createNode(-1, nodetemplate)
                fieldcache.setNode(node)
                result1 = modelCoordinates.assignReal(fieldcache, positions[0])
                result2 = dataCoordinates.assignReal(fieldcache, positions[1])
                assert (result1 == RESULT_OK) and (
                    result2 == RESULT_OK
                ), "Align:  Failed to set up data for alignment to markers optimisation"
                for c in range(3):
                    modelMin[c] = min(modelx[c], modelMin[c])
                    modelMax[c] = max(modelx[c], modelMax[c])
                    dataMin[c] = min(datax[c], dataMin[c])
                    dataMax[c] = max(datax[c], dataMax[c])

            groupScale = 1.0 / len(pointMap)
            modelCM = [(s * groupScale) for s in modelsum]
            dataCM = [(s * groupScale) for s in datasum]
            translationOffset = [(dataCM[c] - modelCM[c]) for c in range(3)]

            modelSpan = [(modelMax[c] - modelMin[c]) for c in range(3)]
            dataSpan = [(dataMax[c] - dataMin[c]) for c in range(3)]
            scaleFactor = max(dataSpan) / max(modelSpan)

            del fieldcache

            # Pre-align to avoid gimbal lock
            translationScaleFactor = 1.0
            first = True
            fieldcache = fieldmodule.createFieldcache()
            modelCoordinatesTransformed, rotation, scale, translation = createFieldsTransformations(
                modelCoordinates, scale_value=scaleFactor)

            # create objective = sum of squares of vector from modelCoordinatesTransformed to dataCoordinates
            markerDiff = fieldmodule.createFieldSubtract(
                dataCoordinates, modelCoordinatesTransformed)
            scaledMarkerDiff = markerDiff * fieldmodule.createFieldConstant(
                [1.0 / translationScaleFactor] * 3)
            objective = fieldmodule.createFieldNodesetSumSquares(
                scaledMarkerDiff, nodes)

            for x in range(2):
                for y in (range(4) if x == 0 else (0, 2)):
                    for z in range(4):
                        azimuth = 0.5 * math.pi * z
                        elevation = 0.5 * math.pi * y
                        roll = 0.5 * math.pi * x
                        rotationAngles = [azimuth, elevation, roll]
                        rotation.assignReal(fieldcache, rotationAngles)
                        rotationMatrix = euler_to_rotation_matrix(
                            rotationAngles)
                        translationFix = mult(
                            sub(matrix_vector_mult(rotationMatrix, modelCM),
                                modelCM), scaleFactor)
                        translation.assignReal(
                            fieldcache, sub(translationOffset, translationFix))
                        result, objectiveValues = objective.evaluateReal(
                            fieldcache, 3)
                        objectiveValue = sum(objectiveValues)

                        if first or (objectiveValue < minObjectiveValue):
                            first = False
                            minObjectiveValue = objectiveValue
                            minRotationAngles = rotationAngles
                            minTranslation = sub(translationOffset,
                                                 translationFix)

            rotation.assignReal(fieldcache, minRotationAngles)
            translation.assignReal(fieldcache, minTranslation)

            assert objective.isValid(
            ), "Align:  Failed to set up objective function for alignment to markers optimisation"

        optimisation = fieldmodule.createOptimisation()
        optimisation.setMethod(Optimisation.METHOD_LEAST_SQUARES_QUASI_NEWTON)
        #optimisation.setMethod(Optimisation.METHOD_QUASI_NEWTON)
        optimisation.addObjectiveField(objective)
        optimisation.addDependentField(rotation)
        optimisation.addDependentField(scale)
        optimisation.addDependentField(translation)

        #FunctionTolerance = optimisation.getAttributeReal(Optimisation.ATTRIBUTE_FUNCTION_TOLERANCE)
        #GradientTolerance = optimisation.getAttributeReal(Optimisation.ATTRIBUTE_GRADIENT_TOLERANCE)
        #StepTolerance = optimisation.getAttributeReal(Optimisation.ATTRIBUTE_STEP_TOLERANCE)
        #MaximumStep = optimisation.getAttributeReal(Optimisation.ATTRIBUTE_MAXIMUM_STEP)
        #MinimumStep = optimisation.getAttributeReal(Optimisation.ATTRIBUTE_MINIMUM_STEP)
        #LinesearchTolerance = optimisation.getAttributeReal(Optimisation.ATTRIBUTE_LINESEARCH_TOLERANCE)
        #TrustRegionSize = optimisation.getAttributeReal(Optimisation.ATTRIBUTE_TRUST_REGION_SIZE)

        #tol_scale = dataScale*dataScale
        #FunctionTolerance *= tol_scale
        #optimisation.setAttributeReal(Optimisation.ATTRIBUTE_FUNCTION_TOLERANCE, FunctionTolerance)
        #GradientTolerance *= tol_scale
        #optimisation.setAttributeReal(Optimisation.ATTRIBUTE_GRADIENT_TOLERANCE, GradientTolerance)
        #StepTolerance *= tol_scale
        #optimisation.setAttributeReal(Optimisation.ATTRIBUTE_STEP_TOLERANCE, StepTolerance)
        #MaximumStep *= tol_scale
        #optimisation.setAttributeReal(Optimisation.ATTRIBUTE_MAXIMUM_STEP, MaximumStep)
        #MinimumStep *= tol_scale
        #optimisation.setAttributeReal(Optimisation.ATTRIBUTE_MINIMUM_STEP, MinimumStep)
        #LinesearchTolerance *= dataScale
        #optimisation.setAttributeReal(Optimisation.ATTRIBUTE_LINESEARCH_TOLERANCE, LinesearchTolerance)
        #TrustRegionSize *= dataScale
        #optimisation.setAttributeReal(Optimisation.ATTRIBUTE_TRUST_REGION_SIZE, TrustRegionSize)

        #if self.getDiagnosticLevel() > 0:
        #    print("Function Tolerance", FunctionTolerance)
        #    print("Gradient Tolerance", GradientTolerance)
        #    print("Step Tolerance", StepTolerance)
        #    print("Maximum Step", MaximumStep)
        #    print("Minimum Step", MinimumStep)
        #    print("Linesearch Tolerance", LinesearchTolerance)
        #    print("Trust Region Size", TrustRegionSize)

        result = optimisation.optimise()
        if self.getDiagnosticLevel() > 1:
            solutionReport = optimisation.getSolutionReport()
            print(solutionReport)
        assert result == RESULT_OK, "Align:  Alignment to markers optimisation failed"

        result1, self._rotation = rotation.evaluateReal(fieldcache, 3)
        result2, self._scale = scale.evaluateReal(fieldcache, 1)
        result3, self._translation = translation.evaluateReal(fieldcache, 3)
        self._translation = [
            s * translationScaleFactor for s in self._translation
        ]
        assert (result1 == RESULT_OK) and (result2 == RESULT_OK) and (
            result3 == RESULT_OK
        ), "Align:  Failed to evaluate transformation for alignment to markers"
Esempio n. 8
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 []
Esempio n. 9
0
def make_tube_bifurcation_points(paCentre, pax, pad2, c1Centre, c1x, c1d2, c2Centre, c2x, c2d2):
    '''
    Gets first ring of coordinates and derivatives between parent pa and
    children c1, c2, and over the crotch between c1 and c2.
    :return rox, rod1, rod2, cox, cod1, cod2
    '''
    paCount = len(pax)
    c1Count = len(c1x)
    c2Count = len(c2x)
    pac1Count, pac2Count, c1c2Count = get_tube_bifurcation_connection_elements_counts(paCount, c1Count, c2Count)
    # convert to number of nodes, includes both 6-way points
    pac1NodeCount = pac1Count + 1
    pac2NodeCount = pac2Count + 1
    c1c2NodeCount = c1c2Count + 1
    paStartIndex = 0
    c1StartIndex = 0
    c2StartIndex = 0
    pac1x  = [ None ]*pac1NodeCount
    pac1d1 = [ None ]*pac1NodeCount
    pac1d2 = [ None ]*pac1NodeCount
    for n in range(pac1NodeCount):
        pan = (paStartIndex + n) % paCount
        c1n = (c1StartIndex + n) % c1Count
        x1, d1, x2, d2 = pax[pan], mult(pad2[pan], 2.0), c1x[c1n], mult(c1d2[c1n], 2.0)
        pac1x [n] = interpolateCubicHermite(x1, d1, x2, d2, 0.5)
        pac1d1[n] = [ 0.0, 0.0, 0.0 ]
        pac1d2[n] = mult(interpolateCubicHermiteDerivative(x1, d1, x2, d2, 0.5), 0.5)
    paStartIndex2 = paStartIndex + pac1Count
    c1StartIndex2 = c1StartIndex + pac1Count
    c2StartIndex2 = c2StartIndex + c1c2Count
    pac2x  = [ None ]*pac2NodeCount
    pac2d1 = [ None ]*pac2NodeCount
    pac2d2 = [ None ]*pac2NodeCount
    for n in range(pac2NodeCount):
        pan = (paStartIndex2 + n) % paCount
        c2n = (c2StartIndex2 + n) % c2Count
        x1, d1, x2, d2 = pax[pan], mult(pad2[pan], 2.0), c2x[c2n], mult(c2d2[c2n], 2.0)
        pac2x [n] = interpolateCubicHermite(x1, d1, x2, d2, 0.5)
        pac2d1[n] = [ 0.0, 0.0, 0.0 ]
        pac2d2[n] = mult(interpolateCubicHermiteDerivative(x1, d1, x2, d2, 0.5), 0.5)
    c1c2x  = [ None ]*c1c2NodeCount
    c1c2d1 = [ None ]*c1c2NodeCount
    c1c2d2 = [ None ]*c1c2NodeCount
    for n in range(c1c2NodeCount):
        c1n = (c1StartIndex2 + n) % c1Count
        c2n = (c2StartIndex2 - n) % c2Count  # note: reversed
        x1, d1, x2, d2 = c2x[c2n], mult(c2d2[c2n], -2.0), c1x[c1n], mult(c1d2[c1n], 2.0)
        c1c2x [n] = interpolateCubicHermite(x1, d1, x2, d2, 0.5)
        c1c2d1[n] = [ 0.0, 0.0, 0.0 ]
        c1c2d2[n] = mult(interpolateCubicHermiteDerivative(x1, d1, x2, d2, 0.5), 0.5)
    # get hex triple points
    hex1, hex1d1, hex1d2 = get_bifurcation_triple_point(
        pax[paStartIndex], mult(pad2[paStartIndex], -1.0),
        c1x[c1StartIndex], c1d2[c1StartIndex],
        c2x[c1StartIndex], c2d2[c2StartIndex])
    hex2, hex2d1, hex2d2 = get_bifurcation_triple_point(
        pax[paStartIndex2], mult(pad2[paStartIndex2], -1.0),
        c2x[c2StartIndex2], c2d2[c2StartIndex2],
        c1x[c1StartIndex2], c1d2[c1StartIndex2])
    # smooth around loops through hex points to get d1
    loop1x  = [ hex2 ] + pac2x[1:-1] + [ hex1 ]
    loop1d1 = [ [ -d for d in hex2d2 ] ] + pac2d1[1:-1] + [ hex1d1 ]
    loop2x  = [ hex1 ] + pac1x[1:-1] + [ hex2 ]
    loop2d1 = [ [ -d for d in hex1d2 ] ] + pac1d1[1:-1] + [ hex2d1 ]
    loop1d1 = smoothCubicHermiteDerivativesLine(loop1x, loop1d1, fixStartDirection=True, fixEndDirection=True, magnitudeScalingMode=DerivativeScalingMode.HARMONIC_MEAN)
    loop2d1 = smoothCubicHermiteDerivativesLine(loop2x, loop2d1, fixStartDirection=True, fixEndDirection=True, magnitudeScalingMode=DerivativeScalingMode.HARMONIC_MEAN)
    # smooth over "crotch" between c1 and c2
    crotchx = [ hex2 ] + c1c2x[1:-1] + [ hex1 ]
    crotchd1 = [ add(hex2d1, hex2d2) ] + c1c2d1[1:-1] + [ [ (-hex1d1[c] - hex1d2[c]) for c in range(3) ] ]
    crotchd1 = smoothCubicHermiteDerivativesLine(crotchx, crotchd1, fixStartDerivative=True, fixEndDerivative=True, magnitudeScalingMode=DerivativeScalingMode.HARMONIC_MEAN)
    rox  = [ hex1 ] + pac1x[1:-1] + [ hex2 ] + pac2x[1:-1]
    rod1 = [ loop1d1[-1] ] + loop2d1[1:] + loop1d1[1:-1]
    rod2 = [ [ -d for d in loop2d1[ 0] ] ] + pac1d2[1:-1] + [ [ -d for d in loop1d1[0] ] ] + pac2d2[1:-1]
    cox  = crotchx [1:-1]
    cod1 = crotchd1[1:-1]
    cod2 = c1c2d2[1:-1]
    return rox, rod1, rod2, cox, cod1, cod2, paStartIndex, c1StartIndex, c2StartIndex
 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)