def DisplayShape(self,
                  shape,
                  vertex_shader=None,
                  fragment_shader=None,
                  map_faces_to_mesh=False,
                  export_edges=False,
                  color=(0.65, 0.65, 0.65),
                  specular_color=(1, 1, 1),
                  shininess=0.9,
                  transparency=0.,
                  line_color=(0, 0., 0.),
                  line_width=2.,
                  mesh_quality=1.):
     # create the shape hash
     shape_uuid = uuid.uuid4().hex
     shape_hash = "shp%s" % shape_uuid
     # tesselate
     tess = Tesselator(shape)
     tess.Compute(compute_edges=export_edges, mesh_quality=mesh_quality)
     #
     sys.stdout.write(
         "\r%s mesh shape, %i triangles" %
         (next(self.spinning_cursor), tess.ObjGetTriangleCount()))
     sys.stdout.flush()
     # export to 3JS
     shape_full_path = os.path.join(self._path, shape_hash + '.json')
     # add this shape to the shape dict, sotres everything related to it
     self._3js_shapes[shape_hash] = [
         export_edges, color, specular_color, shininess, transparency,
         line_color, line_width
     ]
     # generate the mesh
     #tess.ExportShapeToThreejs(shape_hash, shape_full_path)
     # and also to JSON
     with open(shape_full_path, 'w') as json_file:
         json_file.write(tess.ExportShapeToThreejsJSONString(shape_uuid))
     # draw edges if necessary
     edges = []
     if export_edges:
         # export each edge to a single json
         # get number of edges
         nbr_edges = tess.ObjGetEdgeCount()
         for i_edge in range(nbr_edges):
             # after that, the file can be appended
             str_to_write = ''
             edge_point_set = []
             nbr_vertices = tess.ObjEdgeGetVertexCount(i_edge)
             for i_vert in range(nbr_vertices):
                 edge_point_set.append(tess.GetEdgeVertex(i_edge, i_vert))
             # write to file
             edge_hash = "edg%s" % uuid.uuid4().hex
             str_to_write += ExportEdgeToJSON(edge_hash, edge_point_set)
             # create the file
             edge_full_path = os.path.join(self._path, edge_hash + '.json')
             with open(edge_full_path, "w") as edge_file:
                 edge_file.write(str_to_write)
             # store this edge hash
             self._edges_hash.append(edge_hash)
예제 #2
0
 def compute(self):
     shape_tesselator = Tesselator(self._shape)
     shape_tesselator.Compute(compute_edges=self._export_edges,
                              mesh_quality=self._mesh_quality)
     self._triangle_sets.append(shape_tesselator.ExportShapeToX3DIndexedFaceSet())
     # then process edges
     if self._export_edges:
         # get number of edges
         nbr_edges = shape_tesselator.ObjGetEdgeCount()
         for i_edge in range(nbr_edges):
             edge_point_set = []
             nbr_vertices = shape_tesselator.ObjEdgeGetVertexCount(i_edge)
             for i_vert in range(nbr_vertices):
                 edge_point_set.append(shape_tesselator.GetEdgeVertex(i_edge, i_vert))
             ils = ExportEdgeToILS(edge_point_set)
             self._line_sets.append(ils)
예제 #3
0
def draw_shape_mpl(shape):
    """
    Draw a TopoDS_Shape with matplotlib
    """

    tess = Tesselator(shape)

    triangles = []
    edges = []

    # get the triangles
    triangle_count = tess.ObjGetTriangleCount()
    for i_triangle in range(0, triangle_count):
        i1, i2, i3 = tess.GetTriangleIndex(i_triangle)
        triangles.append(
            [tess.GetVertex(i1),
             tess.GetVertex(i2),
             tess.GetVertex(i3)])

    # get the edges
    edge_count = tess.ObjGetEdgeCount()
    for i_edge in range(0, edge_count):
        vertex_count = tess.ObjEdgeGetVertexCount(i_edge)
        edge = []
        for i_vertex in range(0, vertex_count):
            vertex = tess.GetEdgeVertex(i_edge, i_vertex)
            edge.append(vertex)
        edges.append(edge)

    # plot it
    fig = plt.figure()
    ax = Axes3D(fig)

    ax.add_collection3d(Poly3DCollection(triangles, linewidths=0.2, alpha=0.5))
    ax.add_collection3d(Line3DCollection(edges, colors='w', linewidths=1.0))

    ax.get_xaxis().set_visible(True)
    ax.get_yaxis().set_visible(True)
    ax.set_autoscale_on(True)
    plt.show()
예제 #4
0
    def DisplayShape(self,
                     shp,  # the TopoDS_Shape to be displayed
                     shape_color=default_shape_color,  # the default
                     render_edges=False,
                     edge_color=default_edge_color,
                     compute_uv_coords=False,
                     quality=1.0,
                     update=False):
        """ Displays a topods_shape in the renderer instance.
        shp: the TopoDS_Shape to render
        shape_color: the shape color, in html corm, eg '#abe000'
        render_edges: optional, False by default. If True, compute and dislay all
                      edges as a linear interpolation of segments.
        edge_color: optional, black by default. The color used for edge rendering,
                    in html form eg '#ff00ee'
        compute_uv_coords: optional, false by default. If True, compute texture
                           coordinates (required if the shape has to be textured)
        quality: optional, 1.0 by default. If set to something lower than 1.0,
                      mesh will be more precise. If set to something higher than 1.0,
                      mesh will be less precise, i.e. lower numer of triangles.
        update: optional, False by default. If True, render all the shapes.
        """
        # first, compute the tesselation
        tess = Tesselator(shp)
        tess.Compute(uv_coords=compute_uv_coords,
                     compute_edges=render_edges,
                     mesh_quality=quality,
                     parallel=self._parallel)
        # get vertices and normals
        vertices_position = tess.GetVerticesPositionAsTuple()

        number_of_triangles = tess.ObjGetTriangleCount()
        number_of_vertices = len(vertices_position)

        # number of vertices should be a multiple of 3
        assert number_of_vertices % 3 == 0
        assert number_of_triangles * 9 == number_of_vertices

        # then we build the vertex and faces collections as numpy ndarrays
        np_vertices = np.array(vertices_position, dtype='float32').reshape(int(number_of_vertices / 3), 3)
        # Note: np_faces is just [0, 1, 2, 3, 4, 5, ...], thus arange is used
        np_faces = np.arange(np_vertices.shape[0], dtype='uint32')

        # set geometry properties
        buffer_geometry_properties = {'position': BufferAttribute(np_vertices),
                                      'index'   : BufferAttribute(np_faces)}
        if self._compute_normals_mode == NORMAL.SERVER_SIDE:
            # get the normal list, converts to a numpy ndarray. This should not raise
            # any issue, since normals have been computed by the server, and are available
            # as a list of floats
            np_normals = np.array(tess.GetNormalsAsTuple(), dtype='float32').reshape(-1, 3)
            # quick check
            assert np_normals.shape == np_vertices.shape
            buffer_geometry_properties['normal'] = BufferAttribute(np_normals)

        # build a BufferGeometry instance
        shape_geometry = BufferGeometry(attributes=buffer_geometry_properties)

        # if the client has to render normals, add the related js instructions
        if self._compute_normals_mode == NORMAL.CLIENT_SIDE:
            shape_geometry.exec_three_obj_method('computeVertexNormals')

        # then a default material
        shp_material = MeshPhongMaterial(color=shape_color,
                                         polygonOffset=True,
                                         polygonOffsetFactor=1,
                                         polygonOffsetUnits=1,
                                         shininess=0.9)

        # create a mesh unique id
        mesh_id = uuid.uuid4().hex

        # finally create the mash
        shape_mesh = Mesh(geometry=shape_geometry,
                          material=shp_material,
                          name=mesh_id)

        # adds this mesh to the list of meshes
        self._displayed_pickable_objects.add(shape_mesh)

        # and to the dict of shapes, to have a mapping between meshes and shapes
        self._shapes[mesh_id] = shp

        # edge rendering, if set to True
        edge_lines = None
        if render_edges:
            edges = list(map(lambda i_edge: [tess.GetEdgeVertex(i_edge, i_vert) for i_vert in range(tess.ObjEdgeGetVertexCount(i_edge))], range(tess.ObjGetEdgeCount())))
            edges = list(filter(lambda edge: len(edge) == 2, edges))
            np_edge_vertices = np.array(edges, dtype=np.float32).reshape(-1, 3)
            np_edge_indices = np.arange(np_edge_vertices.shape[0], dtype=np.uint32)
            edge_geometry = BufferGeometry(attributes={
                'position': BufferAttribute(np_edge_vertices),
                'index'   : BufferAttribute(np_edge_indices)
            })
            edge_material = LineBasicMaterial(color=edge_color, linewidth=1)
            edge_lines = LineSegments(geometry=edge_geometry, material=edge_material)
            self._displayed_pickable_objects.add(edge_lines)

        if update:
            self.Display()
예제 #5
0
    def AddShapeToScene(self,
                        shp,  # the TopoDS_Shape to be displayed
                        shape_color=default_shape_color,  # the default
                        render_edges=False,
                        edge_color=default_edge_color,
                        compute_uv_coords=False,
                        quality=1.0,
                        transparency=False,
                        opacity=1.):
        # first, compute the tesselation
        tess = Tesselator(shp)
        tess.Compute(uv_coords=compute_uv_coords,
                     compute_edges=render_edges,
                     mesh_quality=quality,
                     parallel=self._parallel)
        # get vertices and normals
        vertices_position = tess.GetVerticesPositionAsTuple()

        number_of_triangles = tess.ObjGetTriangleCount()
        number_of_vertices = len(vertices_position)

        # number of vertices should be a multiple of 3
        assert number_of_vertices % 3 == 0
        assert number_of_triangles * 9 == number_of_vertices

        # then we build the vertex and faces collections as numpy ndarrays
        np_vertices = np.array(vertices_position, dtype='float32').reshape(int(number_of_vertices / 3), 3)
        # Note: np_faces is just [0, 1, 2, 3, 4, 5, ...], thus arange is used
        np_faces = np.arange(np_vertices.shape[0], dtype='uint32')

        # set geometry properties
        buffer_geometry_properties = {'position': BufferAttribute(np_vertices),
                                      'index'   : BufferAttribute(np_faces)}
        if self._compute_normals_mode == NORMAL.SERVER_SIDE:
            # get the normal list, converts to a numpy ndarray. This should not raise
            # any issue, since normals have been computed by the server, and are available
            # as a list of floats
            np_normals = np.array(tess.GetNormalsAsTuple(), dtype='float32').reshape(-1, 3)
            # quick check
            assert np_normals.shape == np_vertices.shape
            buffer_geometry_properties['normal'] = BufferAttribute(np_normals)

        # build a BufferGeometry instance
        shape_geometry = BufferGeometry(attributes=buffer_geometry_properties)

        # if the client has to render normals, add the related js instructions
        if self._compute_normals_mode == NORMAL.CLIENT_SIDE:
            shape_geometry.exec_three_obj_method('computeVertexNormals')

        # then a default material
        shp_material = MeshPhongMaterial(color=shape_color,
                                         polygonOffset=True,
                                         polygonOffsetFactor=1,
                                         polygonOffsetUnits=1,
                                         shininess=0.9,
                                         transparent=transparency)

        # create a mesh unique id
        mesh_id = uuid.uuid4().hex

        # finally create the mash
        shape_mesh = Mesh(geometry=shape_geometry,
                          material=shp_material,
                          name=mesh_id)


        # and to the dict of shapes, to have a mapping between meshes and shapes
        self._shapes[mesh_id] = shp

        # edge rendering, if set to True
        edge_lines = None
        if render_edges:
            edges = list(map(lambda i_edge: [tess.GetEdgeVertex(i_edge, i_vert) for i_vert in range(tess.ObjEdgeGetVertexCount(i_edge))], range(tess.ObjGetEdgeCount())))
            edges = list(filter(lambda edge: len(edge) == 2, edges))
            np_edge_vertices = np.array(edges, dtype=np.float32).reshape(-1, 3)
            np_edge_indices = np.arange(np_edge_vertices.shape[0], dtype=np.uint32)
            edge_geometry = BufferGeometry(attributes={
                'position': BufferAttribute(np_edge_vertices),
                'index'   : BufferAttribute(np_edge_indices)
            })
            edge_material = LineBasicMaterial(color=edge_color, linewidth=1)
            edge_lines = LineSegments(geometry=edge_geometry, material=edge_material)

        # Add geometries to pickable or non pickable objects
        self._displayed_pickable_objects.add(shape_mesh)
        if render_edges:
            self._displayed_non_pickable_objects.add(edge_lines)
예제 #6
0
def generate_png(shape):
	"""
	Draw a TopoDS_Shape with matplotlib
	"""
	from OCC.Visualization import Tesselator
	from mpl_toolkits.mplot3d import Axes3D
	from matplotlib import pyplot as plt
	from mpl_toolkits.mplot3d.art3d import Poly3DCollection, Line3DCollection
	
	tess = Tesselator(shape)
	triangles = []
	edges = []

	# get the triangles
	triangle_count = tess.ObjGetTriangleCount()
	for i_triangle in range(0, triangle_count):
		i1, i2, i3 = tess.GetTriangleIndex(i_triangle)
		triangles.append([tess.GetVertex(i1), tess.GetVertex(i2), tess.GetVertex(i3)])

	# get the edges
	edge_count = tess.ObjGetEdgeCount()
	for i_edge in range(0, edge_count):
		vertex_count = tess.ObjEdgeGetVertexCount(i_edge)
		edge = []
		for i_vertex in range(0, vertex_count):
			vertex = tess.GetEdgeVertex(i_edge, i_vertex)
			edge.append(vertex)
		edges.append(edge)

	# plot it
	fig_side = plt.figure(figsize=(10, 4))
	ax = Axes3D(fig_side)

	ax.add_collection3d(Poly3DCollection(triangles, linewidths=0.15, alpha=0.5))
	ax.add_collection3d(Line3DCollection(edges, colors='w', linewidths=1.0))

	ax.set_axis_off()

	ax.set_xlim(-1800, 1800)
	ax.set_ylim(-800, 800)
	ax.set_zlim(-800, 800)
	ax.view_init(elev=-1., azim=90)
	fig_side.savefig("views/side.png")

	
	fig_top = plt.figure(figsize=(5, 4))
	ax_top = Axes3D(fig_top)

	ax_top.add_collection3d(Poly3DCollection(triangles, linewidths=0.15, alpha=0.5))
	ax_top.add_collection3d(Line3DCollection(edges, colors='w', linewidths=1.0))

	ax_top.set_axis_off()

	ax_top.set_xlim(-2500, 2500)
	ax_top.set_ylim(-50, 450)
	ax_top.set_zlim(-250, 250)
	ax_top.view_init(elev=-1., azim=-2)
	fig_top.savefig("views/back.png")

	ax_top.set_xlim(-2500, 2500)
	ax_top.set_ylim(-50, 450)
	ax_top.set_zlim(-200, 300)
	ax_top.view_init(elev=-1., azim=182)
	fig_top.savefig("views/front.png")