예제 #1
0
def fullflattriareas(surfacemesh):
    ptsP = [P3(*p) for p in surfacemesh["pts"]]
    fptsP = [P2(*p) for p in surfacemesh["fpts"]]
    tris = surfacemesh["tris"]

    def P2Cross(a, b):
        return a.u * b.v - b.u * a.v

    triareas = []
    ftriareas = []
    cornerangs = []
    fcornerangs = []
    for tri in tris:
        p0, p1, p2 = ptsP[tri[0]], ptsP[tri[1]], ptsP[tri[2]]
        parea = 0.5 * P3.Cross(p1 - p0, p2 - p0).Len()
        triareas.append(parea)
        cornerangs.append(P3.Cross(P3.ZNorm(p1 - p0), P3.ZNorm(p2 - p0)).Len())

        f0, f1, f2 = fptsP[tri[0]], fptsP[tri[1]], fptsP[tri[2]]
        farea = 0.5 * abs(P2Cross(f1 - f0, f2 - f0))
        ftriareas.append(farea)
        fcornerangs.append(abs(P2Cross(P2.ZNorm(f1 - f0), P2.ZNorm(f2 - f0))))
    surfacemesh["triareas"] = numpy.array(triareas)
    surfacemesh["ftriareas"] = numpy.array(ftriareas)
    surfacemesh["cornerangs"] = numpy.array(cornerangs)
    surfacemesh["fcornerangs"] = numpy.array(fcornerangs)
예제 #2
0
def StarSplitFace(bm, bar, node):
    lbar, lnode = bar, node
    Dcounts = 0
    pnodebars = []
    while True:
        pnodebars.append((lnode, lbar))
        lnode = lbar.GetNodeFore(lbar.nodeback == lnode)
        if lnode == node:
            break
        lbar = lbar.GetForeRightBL(lbar.nodefore == lnode)
        Dcounts += 1
        assert Dcounts < 1000
    cpt = sum(
        (lnode.p
         for (lnode, lbar) in pnodebars), P3(0, 0, 0)) * (1 / len(pnodebars))
    cnode = bm.NewNode(cpt)
    cnode.pointzone = barmesh.PointZone(0, -1, P3(0, 0, 0))
    np = len(pnodebars)
    cbars = [barmesh.Bar(lnode, cnode) for lnode, lbar in pnodebars]
    for i in range(np):
        cbars[i].barforeright = cbars[i - 1 if i != 0 else np - 1]
        cbars[i].barbackleft = pnodebars[i][
            1]  # cbars[i-1  if i!=0  else np-1]
        lnode, lbar = pnodebars[i]
        lnode = lbar.GetNodeFore(lbar.nodeback == lnode)
        lbar.SetForeRightBL(lbar.nodefore == lnode,
                            cbars[i + 1 if i != np - 1 else 0])
    bm.bars.extend(cbars)
예제 #3
0
def PolyCutBar(ktbar, ktnode1, vc, vch, btop):
    assert not ktbar.bbardeleted, "polycutbar hits deletion"
    Dktbarstart = ktbar
    ktnoded1 = P3.Dot(vc, ktnode1.p)

    assert btop == (P3.Dot(vc, ktbar.nodemid.p) < vch), ("fg", btop,
                                                         P3.Dot(
                                                             vc,
                                                             ktbar.nodemid.p),
                                                         vch)
    #assert ktnoded0 < vch  # not necessarily true if bar points back with mid on end

    Dcount = 0
    while True:
        ktnode0 = ktnode1
        ktnode1 = ktbar.GetNodeFore(ktbar.nodeback == ktnode0)
        ktnoded0 = ktnoded1
        ktnoded1 = P3.Dot(vc, ktnode1.p)
        if btop == (ktnoded1 > vch):
            break
        ktbar = ktbar.GetForeRightBL(ktbar.nodefore == ktnode1)
        assert not ktbar.bbardeleted
        assert Dktbarstart != ktbar
        Dcount += 1
        assert Dcount < 1000
    ktbarlam = (vch - ktnoded0) / (ktnoded1 - ktnoded0)
    return ktnode0, ktbar, ktbarlam
    def DistPtrianglePZ(self, p0, p1, p2):
        v1 = p1 - p0
        v2 = p2 - p0
        v1sq = v1.Lensq()
        v2sq = v2.Lensq()
        v1dv2 = P3.Dot(v1, v2)
        det = v1sq * v2sq - v1dv2**2
        if det == 0.0:
            return  # near zero width triangle has no face to touch
        invdet = 1.0 / det

        # should do distance by the dot on the crossproduct normal

        lv = self.p - p0
        v1dlv = P3.Dot(v1, lv)
        v2dlv = P3.Dot(v2, lv)

        # solve vd = lv - v1 * lam1 - v2 * lam2, where vd.v1 = vd.v2 = 0
        # (v1sq   v1dv2)   ( lam1 )   ( v1dlv )
        # (v1dv2   v2sq) . ( lam2 ) = ( v2dlv )
        lam1 = (v2sq * v1dlv - v1dv2 * v2dlv) * invdet
        lam2 = (-v1dv2 * v1dlv + v1sq * v2dlv) * invdet
        if 0 < lam1 and 0 < lam2 and lam1 + lam2 < 1:
            vd = lv - v1 * lam1 - v2 * lam2
            assert abs(P3.Dot(vd, v1)) < 0.001
            assert abs(P3.Dot(vd, v2)) < 0.001
            vdlen = vd.Len()
            if vdlen < self.r:
                self.r = vdlen
                self.v = -vd
예제 #5
0
    def getbarendclos(self, barstosplit):  # for plotting closest approaches
        pcs = []
        for bar in barstosplit:
            if bar.bbardeleted:
                continue
            if not ((bar.nodeback.pointzone.izone == barmesh.PZ_BEYOND_R) and
                    (bar.nodefore.pointzone.izone == barmesh.PZ_BEYOND_R)):
                continue
            vb = bar.nodefore.p - bar.nodeback.p
            vbsq = vb.Lensq()
            if bar.nodeback.pointzone.v is not None:
                lampcb = P3.Dot(bar.nodeback.pointzone.v, vb) / vbsq
                if 0 < lampcb < 1:
                    dvb = bar.nodeback.pointzone.v - vb * lampcb
                    assert abs(P3.Dot(dvb, vb)) < 0.001
                    dvbsq = dvb.Lensq()
                    if dvbsq < self.rdsq:
                        pcs.append(bar.nodeback.p + bar.nodeback.pointzone.v)

            if bar.nodefore.pointzone.v is not None:
                lampcf = -P3.Dot(bar.nodefore.pointzone.v, vb) / vbsq
                if 0 < lampcf < 1:
                    dvf = bar.nodefore.pointzone.v + vb * lampcf
                    assert abs(P3.Dot(dvf, vb)) < 0.001
                    dvfsq = dvf.Lensq()
                    if dvfsq < self.rdsq:
                        pcs.append(bar.nodeback.p + bar.nodefore.pointzone.v)
        return pcs
예제 #6
0
 def CubeNode(ncode):
     bxlo, bylo, bzlo = (ncode & 0b100, ncode & 0b010, ncode & 0b001)
     node = bm.NewNode(
         P3(xlo if bxlo else xhi, ylo if bylo else yhi,
            zlo if bzlo else zhi))
     node.pointzone = barmesh.PointZone(
         0, -1, P3(w if bxlo else -w, w if bylo else -w, w if bzlo else -w))
     return node
예제 #7
0
    def InsertNodeIntoBarF(self, bar, newnode, bcolinear):
        assert newnode.p != bar.nodeback.p and newnode.p != bar.nodefore.p, newnode.p
        assert newnode in self.nodes

        if __debug__:
            if bcolinear:
                Dv = bar.nodefore.p - bar.nodeback.p
                Dv0 = newnode.p - bar.nodeback.p
                Dlam = P3.Dot(Dv0, Dv) / Dv.Lensq()
                assert 0 < Dlam < 1, Dlam
                Dvd = Dv0 - Dv * Dlam
                assert abs(P3.Dot(Dvd, Dv)) < 0.001
                assert Dvd.Len() < 0.01, (Dv, Dv0)

        barforeleft = bar.GetBarForeLeft()
        barbackright = bar.GetBarBackRight()

        barback = Bar(bar.nodeback, newnode)
        barfore = Bar(bar.nodefore, newnode)

        if bcolinear:  # copy over so we can identify colinearity from creation and not attempt to split along it
            assert (bar.barvecN - barback.barvecN).Len() < 1e-5, (
                bar.nodeback.p, newnode.p, bar.nodefore.p)
            assert (bar.barvecN + barfore.barvecN).Len() < 1e-5, (
                bar.nodeback.p, newnode.p, bar.nodefore.p)
            barback.barvecN = bar.barvecN
            barfore.barvecN = -bar.barvecN

        barback.cellmarkleft, barback.cellmarkright = bar.cellmarkleft, bar.cellmarkright
        barfore.cellmarkright, barfore.cellmarkleft = bar.cellmarkleft, bar.cellmarkright

        if barbackright:
            barback.barforeright = barfore
            barfore.barbackleft = bar.barforeright
            barbackright.SetForeRightBL(barbackright.nodefore == bar.nodeback,
                                        barback)

        if barforeleft:
            barback.barbackleft = bar.barbackleft
            barfore.barforeright = barback
            barforeleft.SetForeRightBL(barforeleft.nodefore == bar.nodefore,
                                       barfore)

        assert not barforeleft or barback.GetBarForeLeft(
        ) == barfore, barback.GetBarForeLeft()
        assert not barbackright or barfore.GetBarForeLeft(
        ) == barback, barfore.GetBarForeLeft()

        self.bars.append(barback)
        self.bars.append(barfore)

        bar.barforeright = barfore
        bar.barbackleft = barback
        bar.bbardeleted = True

        return newnode
 def DistPedgePZ(self, p0, p1):
     lv = self.p - p0
     v = p1 - p0
     vsq = v.Lensq()
     lam = P3.Dot(v, lv) / vsq
     if 0.0 < lam < 1.0:
         vd = lv - v * lam
         assert abs(P3.Dot(vd, v)) < 0.0001
         vdlen = vd.Len()
         if vdlen < self.r:
             self.r = vdlen
             self.v = -vd
예제 #9
0
    def BuildTriangleBarmesh(self, trpts):
        # strip out duplicates in the corner points of the triangles
        ipts, jtrs = [], []
        for i, tr in enumerate(trpts):
            ipts.append((tr[0:3], i * 3 + 0))
            ipts.append((tr[3:6], i * 3 + 1))
            ipts.append((tr[6:9], i * 3 + 2))
            jtrs.append([-1, -1, -1])

        ipts.sort(key=self.nodesortkey)
        prevpt = None
        for pt, i3 in ipts:
            if not prevpt or prevpt != pt:
                self.NewNode(P3(pt[0], pt[1], pt[2]))
                prevpt = pt
            jtrs[i3 // 3][i3 % 3] = len(self.nodes) - 1
        del ipts

        # create the barcycles around each triangle
        tbars = []
        for jt0, jt1, jt2 in jtrs:
            if jt0 != jt1 and jt0 != jt2 and jt1 != jt2:  # are all the points distinct?
                tbars.append(
                    jt0 < jt1 and TriangleBar(self.nodes[jt0], self.nodes[jt1])
                    or TriangleBar(self.nodes[jt1], self.nodes[jt0]))
                tbars.append(
                    jt1 < jt2 and TriangleBar(self.nodes[jt1], self.nodes[jt2])
                    or TriangleBar(self.nodes[jt2], self.nodes[jt1]))
                tbars.append(
                    jt2 < jt0 and TriangleBar(self.nodes[jt2], self.nodes[jt0])
                    or TriangleBar(self.nodes[jt0], self.nodes[jt2]))
                tbars[-3].SetForeRightBL(jt0 < jt1, tbars[-2])
                tbars[-2].SetForeRightBL(jt1 < jt2, tbars[-1])
                tbars[-1].SetForeRightBL(jt2 < jt0, tbars[-3])
        del jtrs

        # strip out duplicates of bars where two triangles meet
        tbars.sort(key=lambda bar:
                   (bar.nodeback.i, bar.nodefore.i, not bar.barbackleft))
        prevbar = None
        for bar in tbars:
            if prevbar and prevbar.nodeback == bar.nodeback and prevbar.nodefore == bar.nodefore and \
                    prevbar.barbackleft and not prevbar.barforeright and not bar.barbackleft and bar.barforeright:
                prevbar.barforeright = bar.barforeright
                node2 = bar.barforeright.GetNodeFore(
                    bar.nodefore == bar.barforeright.nodeback)
                bar2 = bar.barforeright.GetForeRightBL(
                    bar.nodefore == bar.barforeright.nodeback)
                assert bar2.GetNodeFore(bar2.nodeback == node2) == bar.nodeback
                assert bar2.GetForeRightBL(bar2.nodeback == node2) == bar
                bar2.SetForeRightBL(bar2.nodeback == node2, prevbar)
                prevbar = None
            else:
                prevbar = bar
                assert prevbar.i == -1
                prevbar.i = len(self.bars)
                self.bars.append(bar)
        del tbars
    def DistLamPedgePZ(self, p0, p1):
        v = p1 - p0
        vsq = v.Lensq()

        lv = self.p - p0
        # solve |lv + vp * lam - v * mu| == r, where (lv + vp * lam - v * mu) . vp == 0
        mu0 = P3.Dot(lv, v) / vsq
        lvf = lv - v * mu0
        vpdv = P3.Dot(self.vp, v)
        muvp = vpdv / vsq

        vpf = self.vp - v * muvp
        vpfsq = vpf.Lensq()
        if vpfsq == 0.0:
            return
        assert abs(vpfsq - (self.vpsq - muvp * vpdv)) < 0.001

        lvfdvpf = P3.Dot(lvf, vpf)
        lamc = -lvfdvpf / vpfsq
        cp = lvf + vpf * lamc
        cpsq = cp.Lensq()
        lvfsq = lvf.Lensq()
        assert abs(cpsq -
                   (lvfsq + 2 * lvfdvpf * lamc + vpfsq * lamc * lamc)) < 0.001
        assert abs(P3.Dot(cp, vpf)) < 0.001
        llamdsq = self.rsq - cp.Lensq()
        if llamdsq < 0.0:
            return
        lamd = math.sqrt(llamdsq / vpfsq)
        if lamc + lamd < 0.0:
            return
        lam = lamc - lamd
        if lam < 0.0:
            return  # check closer stuff
        if lam > self.lam:
            return
        mu = mu0 + muvp * lam
        if mu < 0 or mu > 1:
            return
        dv = lv + self.vp * lam - v * mu
        assert abs(dv.Len() - self.r) < 0.001
        assert abs(P3.Dot(dv, v)) < 0.001
        self.lam = lam
예제 #11
0
    def calcsplithalfpos(self):
        # midpoint, but could be informed by multiple subdivisions on the rate of curvature
        # should also measure the bc.calccellcuttangency() and find a spot where it is properly wide and doesn't need to be tested
        vch = P3.Dot(self.vc, self.bar.nodemid.p + self.vc * 0.5)

        # find the splitting points
        self.ktnodetop, self.ktbartop, self.ktbartoplam = PolyCutBar(
            self.bar, self.node, self.vc, vch, True)
        self.ktnodebot, self.ktbarbot, self.ktbarbotlam = PolyCutBar(
            self.cbar, self.cbar.GetNodeFore(self.cbar.nodeback == self.cnode),
            self.vc, vch, False)
예제 #12
0
 def __init__(self, fname, Isect=7):
     self.Isect = Isect  # Fix the section all rectangle unwrapping is relative to
     self.sections, self.zvals = loadwinggeometry(fname, 0.001)
     self.nsections = len(self.zvals)
     assert self.nsections == len(self.sections)
     self.nchorddivs = len(self.sections[0])
     assert self.nchorddivs == len(self.sections[-1])
     self.sectionchordlengths = [ ]
     self.sectionchordranges = [ ]
     for section in self.sections:
         chordlengths = [ 0 ]
         for p0, p1 in zip(section, section[1:]):
             chordlengths.append(chordlengths[-1] + (p0-p1).Len())
         self.sectionchordlengths.append(chordlengths)
         self.sectionchordranges.append((-chordlengths[-1]*0.5, chordlengths[-1]*0.5))
     self.leadingedgelengths = [ 0 ]
     for i in range(1, self.nsections):
         p0 = P3.ConvertGZ(self.sectionchordeval(i-1, 0), self.zvals[i-1])
         p1 = P3.ConvertGZ(self.sectionchordeval(i, 0), self.zvals[i])
         self.leadingedgelengths.append(self.leadingedgelengths[-1] + (p0-p1).Len())
     self.urange = (self.leadingedgelengths[0], self.leadingedgelengths[-1])
     self.vrange = self.sectionchordranges[self.Isect]
예제 #13
0
 def __init__(self, nodeback, nodefore):
     self.nodeback = nodeback
     self.nodefore = nodefore
     self.barforeright = None
     self.barbackleft = None
     self.bbardeleted = False
     assert nodefore.i > nodeback.i
     self.nodemid = None  # used to specify a contour cut or a voronoi polygon boundary cut
     self.midcontournumber = -1  # will be set to -2 to denote connecting to out of tolerance/unchecked tolerance trailing contour segment
     self.cellmarkright = None
     self.cellmarkleft = None
     self.barvecN = P3.ZNorm(
         self.nodefore.p - self.nodeback.p
     )  # used to detect colinearity as it's preserved on splitting
예제 #14
0
    def deriveflatpathstretchratios(self, surfacemeshes):
        nodepairreallengths = {}
        nodepairflatlengths = {}
        for surfacemesh in surfacemeshes:
            polynodes = surfacemesh["polynodes"]
            uvpts = surfacemesh["uvpts"]
            pts = surfacemesh["pts"]
            fpts = surfacemesh["fpts"]
            linecontour = surfacemesh["linecontour"]
            for i in range(len(polynodes)):
                n1, n2 = polynodes[i], polynodes[(i + 1) % len(polynodes)]
                p1, p2 = self.nodes[n1], self.nodes[n2]
                i1, i2 = uvpts.index(p1), uvpts.index(p2)
                j1, j2 = linecontour.index(i1), linecontour.index(i2)
                if j2 == 0: j2 = len(linecontour) - 1
                assert (j1 < j2)
                lenreal = sum((P3(*pts[linecontour[j + 1]]) -
                               P3(*pts[linecontour[j]])).Len()
                              for j in range(j1, j2))
                lenflat = sum((P2(*fpts[linecontour[j + 1]]) -
                               P2(*fpts[linecontour[j]])).Len()
                              for j in range(j1, j2))
                nodepairflatlengths[(n1, n2)] = lenflat
                nodepairreallengths[(n1, n2)] = lenreal

        self.flatpathratios = {}
        self.flatpathtable = []
        for i in range(0, len(self.paths), 2):
            n1, n2 = self.paths[i], self.paths[i + 1]
            lenga = nodepairflatlengths.get((n1, n2), -1)
            lengb = nodepairflatlengths.get((n2, n1), -1)
            if lenga != -1 and lengb != -1:
                self.flatpathratios[(n1, n2)] = lenga / lengb
            lengreal = nodepairreallengths.get(
                (n1, n2)) or nodepairreallengths.get((n2, n1)) or -1
            self.flatpathtable.append((n1, n2, lenga, lengb, lengreal))
예제 #15
0
    def calccellcuttangency(
        self
    ):  # could be checked before splitting on the lines to give an option of picking a less tangential position
        assert not self.leadsplitbartop.bbardeleted and not self.leadsplitbarbot.bbardeleted
        node1, bar1, node2, bar2 = self.splitnodetop, self.leadsplitbartop, self.splitnodebot, self.leadsplitbarbot
        bar1a = bar1.GetForeRightBL(bar1.nodefore == node1)
        bar2a = bar2.GetForeRightBL(bar2.nodefore == node2)
        vtopbot = P3.ZNorm(self.splitnodebot.p - self.splitnodetop.p)

        db1 = -node1.cperpbardotN(bar1, vtopbot)
        db1a = node1.cperpbardotN(bar1a, vtopbot)
        db2 = node2.cperpbardotN(bar2, vtopbot)
        db2a = -node2.cperpbardotN(bar2a, vtopbot)

        res = min(db1, db1a, db2, db2a)
        assert res > -0.0001
        return res
예제 #16
0
 def shoulddivide(self, rd, contourdelta, contourdotdiff,
                  b2dcontournormals):
     if self.vc.Len() <= contourdelta:
         return False
     if b2dcontournormals:
         nd = P2.Dot(
             P2.ZNorm(
                 P2(self.bar.nodemid.pointzone.v.x,
                    self.bar.nodemid.pointzone.v.y)),
             P2.ZNorm(
                 P2(self.cbar.nodemid.pointzone.v.x,
                    self.cbar.nodemid.pointzone.v.y)))
     else:
         nd = P3.Dot(self.bar.nodemid.pointzone.v,
                     self.cbar.nodemid.pointzone.v) / (rd * rd)
     if nd >= contourdotdiff:
         return False
     return True
예제 #17
0
def winguv2xyz(uvx, uvy, sections, zvals):
    wingmeshuvudivisions = len(sections)-1
    #print(wingmeshuvudivisions)
    wingmeshuvvdivisions = len(sections[0])
    #print(wingmeshuvvdivisions)
    usecl = uvx*wingmeshuvudivisions
    usec = int(max(0, min(wingmeshuvudivisions-1, math.floor(usecl))))
    ropepointlamda = usecl - usec
    aroundsegmentl = uvy*wingmeshuvvdivisions-1
    aroundsegment = int(max(0, min(wingmeshuvvdivisions-2, math.floor(aroundsegmentl))))
    lambdaCalong = aroundsegmentl - aroundsegment
    p00 = sections[usec][aroundsegment]
    p01 = sections[usec][aroundsegment+1]
    p10 = sections[usec+1][aroundsegment]
    p11 = sections[usec+1][aroundsegment+1]
    z = zvals[usec]*(1-ropepointlamda) + zvals[usec+1]*ropepointlamda
    p0 = p00*(1-ropepointlamda) + p10*ropepointlamda
    p1 = p01*(1-ropepointlamda) + p11*ropepointlamda
    p = p0*(1-lambdaCalong) + p1*lambdaCalong
    return P3(p[0], p[1], z)
    def DistLamPpointPZ(self, p0):
        lv = p0 - self.p
        if lv.z < min(self.vp.z, 0) - self.r or lv.z > max(self.vp.z,
                                                           0) + self.r:
            return
        # |lv - vp * lam| = r
        # qa = vpsq
        qb2 = -P3.Dot(self.vp, lv)
        qc = lv.Lensq() - self.rsq

        qdq = qb2 * qb2 - self.vpsq * qc
        if qdq < 0.0:
            return
        qs = math.sqrt(qdq) / self.vpsq
        qm = -qb2 / self.vpsq
        assert abs(qc + (qm + qs) * (2 * qb2 + (qm + qs) * self.vpsq)) < 0.002
        if qm + qs <= 0.0:
            return
        laml = qm - qs
        if laml < 0.0:
            self.lam = 0.0  # shouldn't happen
        elif laml < self.lam:
            self.lam = laml
예제 #19
0
 def BuildRectBarMesh(self, xpart, ypart, z):
     nxs = xpart.nparts + 1
     nodes = self.nodes
     xbars = []  # multiple of nxs
     ybars = []  # multiple of nxs-1
     self.bars = []
     for y in ypart.vs:
         bfirstrow = (len(nodes) == 0)
         for i in range(nxs):
             nnode = self.NewNode(P3(xpart.vs[i], y, z))
             assert nnode == nodes[-1]
             if not bfirstrow:
                 xbars.append(Bar(nodes[-nxs - 1], nodes[-1]))
                 self.bars.append(xbars[-1])
                 if i != 0:
                     xbars[-1].barbackleft = ybars[1 - nxs]
                     ybars[1 - nxs].barbackleft = xbars[-2]
             if i != 0:
                 ybars.append(Bar(nodes[-2], nodes[-1]))
                 self.bars.append(ybars[-1])
                 if not bfirstrow:
                     ybars[-1].barforeright = xbars[-1]
                     xbars[-2].barforeright = ybars[-1]
     assert len(self.bars) == len(xbars) + len(ybars)
예제 #20
0
 def cperpbardotN(self, bar, v):
     assert self == bar.nodeback or self == bar.nodefore
     vb = (bar.nodefore.p - bar.nodeback.p)
     vbs = (self == bar.nodeback and +1 or -1)
     cperpvb = P3(vb.y * vbs, -vb.x * vbs, 0)
     return P3.Dot(cperpvb, v) / vb.Len()
예제 #21
0
    def splitbarsdirectionchangesR(self, barstosplit):
        barsplitsdc = []
        bsdsq = self.barsplitdelta * self.barsplitdelta
        for bar in barstosplit:
            if bar.bbardeleted:
                continue
            if not ((bar.nodeback.pointzone.izone == barmesh.PZ_BEYOND_R) and
                    (bar.nodefore.pointzone.izone == barmesh.PZ_BEYOND_R)):
                continue
            vb = bar.nodefore.p - bar.nodeback.p
            vbsq = vb.Lensq()
            if vbsq < bsdsq:
                continue
            lamclossplit = -1
            dvbsq = -1
            if bar.nodeback.pointzone.v is not None:
                lampcb = P3.Dot(bar.nodeback.pointzone.v, vb) / vbsq
                if 0 < lampcb < 1:
                    dvb = bar.nodeback.pointzone.v - vb * lampcb
                    assert abs(P3.Dot(dvb, vb)) < 0.001
                    dvbsq = dvb.Lensq()
                    if dvbsq < self.rdsq:
                        lamclossplit = lampcb

            if bar.nodefore.pointzone.v is not None:
                lampcf = -P3.Dot(bar.nodefore.pointzone.v, vb) / vbsq
                if 0 < lampcf < 1:
                    dvf = bar.nodefore.pointzone.v + vb * lampcf
                    assert abs(P3.Dot(dvf, vb)) < 0.001
                    dvfsq = dvf.Lensq()
                    if dvfsq < self.rdsq:
                        if lamclossplit == -1 or dvfsq < dvbsq:
                            lamclossplit = 1 - lampcf

            if lamclossplit != -1:
                barsplitsdc.append((bar, lamclossplit))

        # split the bars
        nowsplitbars = []
        splitnodes = []
        for bar, lamc in barsplitsdc:
            splitnode = self.bm.InsertNodeIntoBarF(
                bar,
                self.bm.NewNode(Along(lamc, bar.nodeback.p, bar.nodefore.p)),
                True)
            assert bar.bbardeleted
            splitnodes.append(splitnode)
            nowsplitbars.append(bar.barforeright)
            nowsplitbars.append(bar.barbackleft)

        # make the measurements on all the new splitnodes
        self.MakePointZoneRFS(splitnodes)

        # make the measurements on all the new bars
        newbarpolycuts = []
        for bar in nowsplitbars:
            if IsCutBar(bar, barmesh.PZ_BEYOND_R):
                newbarpolycuts.append(bar)

        self.CutbarRFS(newbarpolycuts)
        #print("splitbarsdirectionchanges", len(barstosplit), len(nowsplitbars))
        return nowsplitbars
    def DistLamPtrianglePZ(self, p0, p1, p2):
        # solve vd = lv + vp * lam - v1 * lam1 - v2 * lam2, where |vd| = r and vd.v1 = vd.v2 = 0
        # solve +-r = (lv + vp * lam) . vnorm = lv . vnorm + vp . vnorm lam
        v1 = p1 - p0
        v2 = p2 - p0
        vcross = P3.Cross(v1, v2)
        assert abs(P3.Dot(vcross, v1)) < 0.001
        assert abs(P3.Dot(vcross, v2)) < 0.001
        vnorm = P3.ZNorm(vcross)

        lv = self.p - p0
        lvdvnorm = P3.Dot(lv, vnorm)
        vpdvnorm = P3.Dot(self.vp, vnorm)
        if vpdvnorm == 0.0:
            return
        # lam = (+-r - lvdvnorm)/vpdvnorm
        if vpdvnorm > 0.0:
            lam = (-self.r - lvdvnorm) / vpdvnorm
        else:
            lam = (self.r - lvdvnorm) / vpdvnorm
        if lam < 0 or lam > self.lam:
            return

        lvl = lv + self.vp * lam
        v1dlv = P3.Dot(v1, lvl)
        v2dlv = P3.Dot(v2, lvl)
        v1sq = v1.Lensq()
        v2sq = v2.Lensq()
        v1dv2 = P3.Dot(v1, v2)
        det = v1sq * v2sq - v1dv2**2
        if det == 0.0:
            return  # no face size
        invdet = 1.0 / det

        # solve vd = lv - v1 * lam1 - v2 * lam2, where vd.v1 = vd.v2 = 0
        # (v1sq   v1dv2)   ( lam1 )   ( v1dlv )
        # (v1dv2   v2sq) . ( lam2 ) = ( v2dlv )
        lam1 = (v2sq * v1dlv - v1dv2 * v2dlv) * invdet
        lam2 = (-v1dv2 * v1dlv + v1sq * v2dlv) * invdet
        if 0 < lam1 and 0 < lam2 and lam1 + lam2 < 1:
            vd = lvl - v1 * lam1 - v2 * lam2
            assert abs(P3.Dot(vd, v1)) < 0.001
            assert abs(P3.Dot(vd, v2)) < 0.001
            assert abs(vd.Len() - self.r) < 0.001
            self.lam = lam
예제 #23
0
def AlongP3Z(z, p0, p1):
    assert (p0.z < z) != (p1.z < z) or p0.z == z, (p0.z, z, p1.z)
    lam = (z - p0.z) / (p1.z - p0.z)
    assert 0.0 <= lam <= 1.0
    return P3(p0.x * (1 - lam) + p1.x * lam, p0.y * (1 - lam) + p1.y * lam, z)
예제 #24
0
 def sevalI(self, p):
     i = max(0, min(self.nsections-2, int(p[0])))
     m = p[0] - i
     p0 = P3.ConvertGZ(self.sectionchordevalI(i, p[1]), self.zvals[i])
     p1 = P3.ConvertGZ(self.sectionchordevalI(i+1, p[1]), self.zvals[i+1])
     return p0*(1-m) + p1*m
예제 #25
0
 def seval(self, p):
     if p[0] < 0.0:
         s = self.sevalI(self.sevalconv((-p[0], p[1])))
         return P3(s.x, s.y, -s.z)                       
     return self.sevalI(self.sevalconv(p))
예제 #26
0
 def GetNodePoint(self, i):
     return P3(*self.nnodes[i,])