Esempio n. 1
0
    def __init__(self, filename, mm_x=40.0, mm_y=0.0, mm_depth=3.0):
        self.filename = filename
        rawImage = Image.open(filename)
        self.im = ImageOps.grayscale(rawImage)  # winnow down to one channel
        self.pix = self.im.load()
        #resize-- max dim ~160 px?
        ratio = 1.0
        if self.im.size[0] > self.im.size[1]:
            if self.im.size[0] > MAX_DIM:
                ratio = float(self.im.size[0]) / MAX_DIM
        else:
            if self.im.size[1] > MAX_DIM:
                ratio = MAX_DIM / float(self.im.size[1])
        if ratio != 1.0:
            print self.im.size[0], self.im.size[0] * ratio
            self.im.resize((self.im.size[0] * ratio, self.im.size[1] * ratio))

        self.pixels_x, self.pixels_y = self.im.size
        print "image size x=", self.pixels_x, " y=", self.pixels_y

        self.min_val, self.max_val = self.im.getextrema()
        print "extrema", self.min_val, self.max_val
        self.mm_x = mm_x
        if mm_y:
            self.mm_y = mm_y
        else:
            # keep aspect ratio
            self.mm_y = self.mm_x * self.pixels_y / self.pixels_x
        self.mm_depth = mm_depth
        self.surf = gts.Surface()
Esempio n. 2
0
def convert(ddxml_in, oogl_out):
    """
Main function to convert the given in file into the given out file(s).
	"""
    global levels

    # setup expat
    pxml = xml.parsers.expat.ParserCreate()
    decoder = ddxml_decoder()

    pxml.StartElementHandler = decoder.start
    pxml.EndElementHandler = decoder.stop
    pxml.CharacterDataHandler = decoder.data

    # read in ddxml
    fd = open(ddxml_in, 'r')
    data = fd.read()
    fd.close()

    # parse and sanity checks
    pxml.Parse(data)

    if 0 == len(decoder.surfaces):
        print('Error: No surfaces found, missing mesh or bad ddxml')
        return

    mesh_count = 0
    for surface in decoder.surfaces:
        print('Mesh %d:' % mesh_count)

        # for each mesh produce a reduced model
        for level in levels:
            target = levels[level] / 100.0
            target *= surface.stats()['n_faces']

            stemp = gts.Surface().copy(surface)

            if 0 != level:
                stemp.coarsen(int(target))

            fd = open(oogl_out % (mesh_count, level), 'w+')
            stemp.write_oogl(fd)
            fd.close()

            print('\tWrote level %d with %d faces' %
                  (level, stemp.stats()['n_faces']))
        mesh_count += 1
Esempio n. 3
0
def sweptPolylines2gtsSurface(pts,threshold=0,capStart=False,capEnd=False):
	"""Create swept suface (as GTS triangulation) given same-length sequences of points (as 3-tuples).

If threshold is given (>0), then

* degenerate faces (with edges shorter than threshold) will not be created
* gts.Surface().cleanup(threshold) will be called before returning, which merges vertices mutually closer than threshold. In case your pts are closed (last point concident with the first one) this will the surface strip of triangles. If you additionally have capStart==True and capEnd==True, the surface will be closed.

.. note:: capStart and capEnd make the most naive polygon triangulation (diagonals) and will perhaps fail for non-convex sections.

.. warning:: the algorithm connects points sequentially; if two polylines are mutually rotated or have inverse sense, the algorithm will not detect it and connect them regardless in their given order.
	"""
	import gts # will raise an exception in gts-less builds
	if not len(set([len(pts1) for pts1 in pts]))==1: raise RuntimeError("Polylines must be all of the same length!")
	vtxs=[[gts.Vertex(x,y,z) for x,y,z in pts1] for pts1 in pts]
	sectEdges=[[gts.Edge(vtx[i],vtx[i+1]) for i in range(0,len(vtx)-1)] for vtx in vtxs]
	interSectEdges=[[] for i in range(0,len(vtxs)-1)]
	for i in range(0,len(vtxs)-1):
		for j in range(0,len(vtxs[i])):
			interSectEdges[i].append(gts.Edge(vtxs[i][j],vtxs[i+1][j]))
			if j<len(vtxs[i])-1: interSectEdges[i].append(gts.Edge(vtxs[i][j],vtxs[i+1][j+1]))
	if threshold>0: # replace edges of zero length with None; their faces will be skipped
		def fixEdges(edges):
			for i,e in enumerate(edges):
				if (Vector3(e.v1.x,e.v1.y,e.v1.z)-Vector3(e.v2.x,e.v2.y,e.v2.z)).norm()<threshold: edges[i]=None
		for ee in sectEdges: fixEdges(ee)
		for ee in interSectEdges: fixEdges(ee)
	surf=gts.Surface()
	for i in range(0,len(vtxs)-1):
		for j in range(0,len(vtxs[i])-1):
			ee1=interSectEdges[i][2*j+1],sectEdges[i+1][j],interSectEdges[i][2*j]
			ee2=sectEdges[i][j],interSectEdges[i][2*j+2],interSectEdges[i][2*j+1]
			if None not in ee1: surf.add(gts.Face(interSectEdges[i][2*j+1],sectEdges[i+1][j],interSectEdges[i][2*j]))
			if None not in ee2: surf.add(gts.Face(sectEdges[i][j],interSectEdges[i][2*j+2],interSectEdges[i][2*j+1]))
	def doCap(vtx,edg,start):
		ret=[]
		eFan=[edg[0]]+[gts.Edge(vtx[i],vtx[0]) for i in range(2,len(vtx))]
		for i in range(1,len(edg)):
			ret+=[gts.Face(eFan[i-1],eFan[i],edg[i]) if start else gts.Face(eFan[i-1],edg[i],eFan[i])]
		return ret
	caps=[]
	if capStart: caps+=doCap(vtxs[0],sectEdges[0],start=True)
	if capEnd: caps+=doCap(vtxs[-1],sectEdges[-1],start=False)
	for cap in caps: surf.add(cap)
	if threshold>0: surf.cleanup(threshold)
	return surf
Esempio n. 4
0
    def convert(self):
        """
Converts the data from the current/last mesh node. Each triangle is made up of
1 or more triangles.
		"""
        tri = []
        self.surface = gts.Surface()
        for index in self.indices:
            tri.append(index)

            # for every group of 3 indicies
            if 3 == len(tri):
                e1 = gts.Edge(self.vertices[tri[0]], self.vertices[tri[1]])
                e2 = gts.Edge(self.vertices[tri[1]], self.vertices[tri[2]])
                e3 = gts.Edge(self.vertices[tri[2]], self.vertices[tri[0]])
                self.surface.add(gts.Face(e1, e2, e3))
                tri = []
def unitSquare():
    """Return square composed of 2 facets in the xy plane, centered at zero with unit extents."""
    import gts
    vv = [
        gts.Vertex(1, 1, 0),
        gts.Vertex(-1, 1, 0),
        gts.Vertex(-1, -1, 0),
        gts.Vertex(1, -1, 0)
    ]
    ee = [
        gts.Edge(vv[0], vv[1]),
        gts.Edge(vv[1], vv[2]),
        gts.Edge(vv[2], vv[3]),
        gts.Edge(vv[3], vv[0]),
        gts.Edge(vv[0], vv[2])
    ]
    surf = gts.Surface()
    surf.add(gts.Face(ee[0], ee[1], ee[4]))
    surf.add(gts.Face(ee[2], ee[3], ee[4]))
    return surf
Esempio n. 6
0
def test_tetrahedron():
    """
    A tetrahedron is assembled from these primitives as follows.  
    First, create Vertices for each of the tetrahedron's points:
    """
    v1 = gts.Vertex(1, 1, 1)
    v2 = gts.Vertex(-1, -1, 1)
    v3 = gts.Vertex(-1, 1, -1)
    v4 = gts.Vertex(1, -1, -1)
    """
    Next, connect the four vertices to create six unique Edges:
    """
    e1 = gts.Edge(v1, v2)
    e2 = gts.Edge(v2, v3)
    e3 = gts.Edge(v3, v1)
    e4 = gts.Edge(v1, v4)
    e5 = gts.Edge(v4, v2)
    e6 = gts.Edge(v4, v3)
    """
    The four triangular faces are composed using three edges each:
    """
    f1 = gts.Face(e1, e2, e3)
    f2 = gts.Face(e1, e4, e5)
    f3 = gts.Face(e2, e5, e6)
    f4 = gts.Face(e3, e4, e6)
    """
    Finally, the surface is assembled from the faces.
    Some care must be taken in the orientation of the faces.  
    In the above example, the surface normals are pointing inward, 
    and so the surface technically defines a void, rather than a solid.  
    To create a tetrahedron with surface normals pointing outward, 
    use the following instead:
    """
    s = gts.Surface()
    for face in [f1, f2, f3, f4]:
        if not face.is_compatible(s):
            face.revert()
        s.add(face)

    print s.volume()
    print s.center_of_mass()
Esempio n. 7
0
create union of surfaces using GTS calls first and use a single
isGtsSurface as predicate with the united surface.

The disadvantage of the predicate union | is that each sphere must fit whole in one
surface or another: with padding, several points on the sphere are tested. Therefore,
areas near both surfaces' boundary will not be filled at all.

Note that GTS only moves references to surfaces around, therefore e.g. translating
surface that is part of the union will move also the part of the united surface.
Therefore, we use the copy() method for deep copy here.
"""
from woo import pack, qt
import gts

s1 = gts.read(open('horse.coarse.gts'))
s2 = gts.Surface()
s2.copy(s1)
s2.translate(0.04, 0, 0)
O.bodies.append(
    pack.gtsSurface2Facets(s1, color=(0, 1, 0)) +
    pack.gtsSurface2Facets(s2, color=(1, 0, 0)))

s12 = gts.Surface()
s12.copy(s1.union(s2))
s12.translate(0, 0, .1)
radius = 0.002
O.bodies.append(pack.gtsSurface2Facets(s12, color=(0, 0, 1)))

qt.View()
from time import time
t0 = time()
Esempio n. 8
0
edge = []
for i in list(range(discret)):
    if i == discret - 1:
        edge.append([
            gts.Edge(pcenter, pt[i]),
            gts.Edge(pt[i], pt[0]),
            gts.Edge(pt[0], pcenter)
        ])
    else:
        edge.append([
            gts.Edge(pcenter, pt[i]),
            gts.Edge(pt[i], pt[i + 1]),
            gts.Edge(pt[i + 1], pcenter)
        ])

# creation des faces des triangles
face = []
for i in list(range(discret)):
    face.append(gts.Face(edge[i][0], edge[i][1], edge[i][2]))

# creation de la surface et importation dans la simulation
s = gts.Surface()
for i in list(range(discret)):
    s.add(face[i])

#print s.area()
#print math.pi*radius**2.

facet = gtsSurface2Facets(s, wire=False, material=wallMat)
O.bodies.append(facet)
Esempio n. 9
0
    def buildsectionsurface(cls, s):
        import gts
        from morphforge.core import LocMgr
        from os.path import join as Join
        print 'Building Mesh'

        working_dir = LocMgr.ensure_dir_exists('/tmp/mf/mesh/')
        fTemp1 = Join(working_dir, 'pts.txt')
        fTemp2 = Join(working_dir, 'pts.off')
        fTemp3 = Join(working_dir, 'pts.stl')
        fTemp2b = Join(working_dir, 'pts_postSub.off')
        fTemp4 = Join(working_dir, 'pts.gts')

        nstep = 5
        print 'Building Spheres'
        distal_offset = np.array((0.05, 0.05, 0.05))
        ptsP = GeomTools.produce_sphere(centre=s.get_proximal_npa3(),
                                        radius=s.p_r,
                                        n_steps=nstep)
        ptsD = GeomTools.produce_sphere(centre=s.get_distal_npa3() +
                                        distal_offset,
                                        radius=s.d_r,
                                        n_steps=nstep)

        print 'Removing Close Points'
        pts = cls.only_pts_at_min_dist(ptsP + ptsD, min_dist=0.01)

        print 'Writing:', fTemp2
        with open(fTemp1, 'w') as f:
            f.write('3 %d\n' % len(pts))
            np.savetxt(f, np.array(pts))

        if os.path.exists(fTemp2):
            os.unlink(fTemp2)
        os.system('qhull T1 QJ o < %s > %s' % (fTemp1, fTemp2))

        # Don't do the subdivision, just copy the files:
        os.system('cp %s %s' % (fTemp2, fTemp2b))
        # fTemp2 = fTemp2b

        f = open(fTemp2b).read().split()
        (nVertex, nFace, nEdge) = [int(i) for i in f[1:4]]
        assert nVertex > 5
        vertices = np.array([float(t) for t in f[4:4 + nVertex * 3]
                             ]).reshape(nVertex, 3)

        triangles = np.array([int(t) for t in f[4 + nVertex * 3:]])
        triangles = triangles.reshape((nFace, 4))
        triangles = triangles[:, (1, 2, 3)]

        print 'Writing STL'
        with open(fTemp3, 'w') as fSTL:
            fSTL.write('solid name\n')
            for i in range(triangles.shape[0]):
                (a, b, c) = triangles[i, :]

                fSTL.write('facet normal 0 0 0\n')
                fSTL.write('outer loop \n')
                fSTL.write('vertex %f %f %f\n' %
                           (vertices[a, 0], vertices[a, 1], vertices[a, 2]))
                fSTL.write('vertex %f %f %f\n' %
                           (vertices[b, 0], vertices[b, 1], vertices[b, 2]))
                fSTL.write('vertex %f %f %f\n' %
                           (vertices[c, 0], vertices[c, 1], vertices[c, 2]))
                fSTL.write('endloop \n')
                fSTL.write('endfacet\n')

            fSTL.write('solid end')

        print 'Running stl2gts...'
        if os.path.exists(fTemp4):
            os.unlink(fTemp4)

        os.system('stl2gts < %s > %s' % (fTemp3, fTemp4))

        assert os.path.exists(fTemp4)

        import gts
        f = open(fTemp4)
        s = gts.Surface()
        s = gts.read(f)

        s.cleanup()
        assert s.is_closed()
        assert s.is_orientable()

        # s.tessellate()
        return s
Esempio n. 10
0
create union of surfaces using GTS calls first and use a single
isGtsSurface as predicate with the united surface.

The disadvantage of the predicate union | is that each sphere must fit whole in one
surface or another: with padding, several points on the sphere are tested. Therefore,
areas near both surfaces' boundary will not be filled at all.

Note that GTS only moves references to surfaces around, therefore e.g. translating
surface that is part of the union will move also the part of the united surface.
Therefore, we use the copy() method for deep copy here.
"""
from woo import pack,qt
import gts

s1=gts.read(open('horse.coarse.gts'))
s2=gts.Surface(); s2.copy(s1); s2.translate(0.04,0,0)
O.bodies.append(pack.gtsSurface2Facets(s1,color=(0,1,0))+pack.gtsSurface2Facets(s2,color=(1,0,0)))

s12=gts.Surface(); s12.copy(s1.union(s2)); s12.translate(0,0,.1)
radius=0.002
O.bodies.append(pack.gtsSurface2Facets(s12,color=(0,0,1)))

qt.View()
from time import time
t0=time()
O.bodies.append(pack.regularHexa(pack.inGtsSurface(s1) | pack.inGtsSurface(s2),radius,gap=0,color=(0,1,0)))
t1=time()
print('Using predicate union: %gs'%(t1-t0))
O.bodies.append(pack.regularHexa(pack.inGtsSurface(s12),radius,gap=0.,color=(1,0,0)))
t2=time()
print('Using surface union: %gs'%(t2-t1))