def centerline(F, dir, nx=2, mode=2, th=0.2): """Compute the centerline in the direction dir. """ bb = F.bbox() x0 = F.center() x1 = F.center() x0[dir] = bb[0][dir] x1[dir] = bb[1][dir] n = array((0, 0, 0)) n[dir] = nx grid = simple.regularGrid(x0, x1, n, swapaxes=True).reshape((-1, 3)) th *= (x1[dir] - x0[dir]) / nx n = zeros((3, )) n[dir] = 1.0 def localCenter(X, P, n): """Return the local center of points X in the plane P,n""" test = abs(X.distanceFromPlane(P, n)) < th # points close to plane if mode == 1: C = X[test].center() elif mode == 2: C = X[test].centroid() return C center = [localCenter(F, P, n) for P in grid] return PolyLine(center)
def create(): """Create a closed surface and a set of points.""" nx, ny, nz = npts # Create surface if surface == 'file': S = TriSurface.read(filename).centered() elif surface == 'sphere': S = simple.sphere(ndiv=grade) if refine > S.nedges(): S = S.refine(refine) draw(S, color='red') if not S.isClosedManifold(): warning("This is not a closed manifold surface. Try another.") return None, None # Create points if points == 'grid': P = simple.regularGrid([-1., -1., -1.], [1., 1., 1.], [nx-1, ny-1, nz-1]) else: P = random.rand(nx*ny*nz*3) sc = array(scale) siz = array(S.sizes()) tr = array(trl) P = Formex(P.reshape(-1, 3)).resized(sc*siz).centered().translate(tr*siz) draw(P, marksize=1, color='black') zoomAll() return S, P
def run(): clear() # Create a grid of points with X = Coords( regularGrid([0., 0., 0.], [1., 1., 0.], [3, 3, 0]).reshape(-1, 3)) X = X.addNoise(rsize=0.05, asize=0.0) draw(X) drawNumbers(X) ind = geomtools.closest(X) M = connect([X, X[ind]]).toMesh().removeDuplicate() # Hint: the connect() function transforms all items in the first # argument to Formices. Thus it also works directly with Coords objects. draw(M) drawNumbers(M, color='red')
def cone1(r0, r1, h, t=360., nr=1, nt=24, diag=None): """Constructs a Formex which is (a sector of) a circle / (truncated) cone / cylinder. r0,r1,h are the lower and upper radius and the height of the truncated cone. All can be positive, negative or zero. Special cases: r0 = r1 : cylinder h = 0 : (flat) circle r0 = 0 or r1 = 0 : untruncated cone Only a sector of the structure, with opening angle t, is modeled. The default results in a full circumference. The cone is modeled by nr elements in height direction and nt elements in circumferential direction. By default, the result is a 4-plex Formex whose elements are quadrilaterals (some of which may collapse into triangles). If diag='up' or diag = 'down', all quads are divided by an up directed diagonal and a plex-3 Formex results. """ r0, r1, h, t = [float(f) for f in (r0, r1, h, t)] p = Formex( simple.regularGrid([r0, 0., 0.], [r1, h, 0.], [0, nr, 0]).reshape(-1, 3)) #draw(p,color=red) a = (r1 - r0) / h if a != 0.: p = p.shear(0, 1, a) #draw(p) q = p.rotate(t / nt, axis=1) #draw(q,color=green) if diag == 'u': F = connect([p, p, q], bias=[0, 1, 1]) + \ connect([p, q, q], bias=[1, 2, 1]) elif diag == 'd': F = connect([q, p, q], bias=[0, 1, 1]) + \ connect([p, p, q], bias=[1, 2, 1]) else: F = connect([p, p, q, q], bias=[0, 1, 1, 0]) F = Formex.concatenate([F.rotate(i * t / nt, 1) for i in range(nt)]) return F
def run(): clear() transparent() nquad = 1 nsphere = 5 S = sphere(nsphere) #Creating the points to define the intersecting lines R = regularGrid([0., 0., 0.], [0., 1., 1.], [1, nquad, nquad]) L0 = Coords(R.reshape(-1, 3)).trl([-2., -1. / 2, -1. / 2]).fuse()[0] L1 = L0.trl([4., 0., 0.]) P, X = S.intersectionWithLines(q=L0, q2=L1, method='line', atol=1e-5) # Retrieving the index of the points and the correspending lines and hit triangles id_pts = X[:, 0] id_intersected_line = X[:, 1] id_hit_triangle = X[:, 2] hitsxline = inverseIndex(id_intersected_line.reshape(-1, 1)) Nhitsxline = (hitsxline > -1).sum(axis=1) ptsok = id_pts[hitsxline[where(hitsxline > -1)]] hittriangles = id_hit_triangle[hitsxline[where(hitsxline > -1)]] colors = ['red', 'green', 'blue', 'cyan'] [ draw(Formex([[p0, p1]]), color=c, linewidth=2, alpha=0.7) for p0, p1, c in zip(L0, L1, colors) ] id = 0 for icolor, nhits in enumerate(Nhitsxline): for i in range(nhits): draw(P[ptsok][id], color=colors[icolor], marksize=5, alpha=1) draw(S.select([hittriangles[id]]), ontop=True, color=colors[icolor]) id += 1 draw(S, alpha=0.3)
) Hex20.drawfaces = [Hex20.faces.selectNodes(i) for i in Quad8.drawfaces] Hex20.drawfaces2 = [Hex20.faces] Hex20.drawgl2edges = [Hex20.edges.selectNodes(i) for i in Line3.drawgl2faces] Hex20.drawgl2faces = [Hex20.faces.selectNodes(i) for i in Quad8.drawgl2faces] # THIS ELEMENT USES A REGULAR NODE NUMBERING!! # WE MIGHT SWITCH OTHER ELEMENTS TO THIS REGULAR SCHEME TOO # AND ADD THE RENUMBERING TO THE FE OUTPUT MODULES from pyformex.simple import regularGrid Hex27 = createElementType( 'hex27', "A 27-node hexahedron", ndim=3, vertices=regularGrid([0., 0., 0.], [1., 1., 1.], [2, 2, 2]).reshape(-1, 3), edges=( 'line3', [(0, 1, 2), (6, 7, 8), (18, 19, 20), (24, 25, 26), (0, 3, 6), (2, 5, 8), (18, 21, 24), (20, 23, 26), (0, 9, 18), (2, 11, 20), (6, 15, 24), (8, 17, 26)], ), faces=( 'quad9', [ (0, 18, 24, 6, 9, 21, 15, 3, 12), (2, 8, 26, 20, 5, 17, 23, 11, 14), (0, 2, 20, 18, 1, 11, 19, 9, 10), (6, 24, 26, 8, 15, 25, 17, 7, 16), (0, 6, 8, 2, 3, 7, 5, 1, 4), (18, 20, 26, 24, 19, 23, 25, 21, 22),