Exemplo n.º 1
0
def OpenCascadeMeshHierarchy(stepfile, element_size, levels, comm=COMM_WORLD, distribution_parameters=None, callbacks=None, order=1, mh_constructor=MeshHierarchy, cache=True, verbose=True, gmsh="gmsh", project_refinements_to_cad=True, reorder=None):

    # OpenCascade doesn't give a nice error message if stepfile
    # doesn't exist, it segfaults ...

    try:
        from OCC.Core.STEPControl import STEPControl_Reader
        from OCC.Extend.TopologyUtils import TopologyExplorer
    except ImportError:
        raise ImportError("To use OpenCascadeMeshHierarchy, you must install firedrake with the OpenCascade python bindings (firedrake-update --opencascade).")

    if not os.path.isfile(stepfile):
        raise OSError("%s does not exist" % stepfile)

    step_reader = STEPControl_Reader()
    step_reader.ReadFile(stepfile)
    step_reader.TransferRoot()
    shape = step_reader.Shape()
    cad = TopologyExplorer(shape)
    dim = 3 if cad.number_of_solids() > 0 else 2
    coarse = make_coarse_mesh(stepfile, cad, element_size, dim, comm=comm, distribution_parameters=distribution_parameters, cache=cache, verbose=verbose, gmsh=gmsh)

    mh = mh_constructor(coarse, levels, distribution_parameters=distribution_parameters, callbacks=callbacks, reorder=reorder)
    project_to_cad = project_mesh_to_cad_2d if dim == 2 else project_mesh_to_cad_3d

    if project_refinements_to_cad:
        for mesh in mh:
            project_to_cad(mesh, cad)
        mh.nested = False

    if order > 1:
        VFS = VectorFunctionSpace
        Ts = [
            Function(VFS(mesh, "CG", order)).interpolate(mesh.coordinates)
            for mesh in mh]
        ho_meshes = [Mesh(T) for T in Ts]
        mh = HierarchyBase(
            ho_meshes, mh.coarse_to_fine_cells,
            mh.fine_to_coarse_cells,
            refinements_per_level=mh.refinements_per_level, nested=mh.nested
        )
        if project_refinements_to_cad:
            for mesh in mh:
                project_to_cad(mesh, cad)
        else:
            project_to_cad(mh[0], cad)
            for i in range(1, len(mh)):
                prolong(Ts[i-1], Ts[i])
    return mh
Exemplo n.º 2
0
    def read_file(self):
        """Build tree = treelib.Tree() to facilitate displaying the CAD model and

        constructing the tree view showing the assembly/component relationships.
        Each node of self.tree contains the following:
        (Name, UID, ParentUID, {Data}) where the Data keys are:
        'a' (isAssy?), 'l' (TopLoc_Location), 'c' (Quantity_Color), 's' (TopoDS_Shape)
        """
        logger.info("Reading STEP file")
        tmodel = TreeModel("STEP")
        self.shape_tool = tmodel.shape_tool
        self.color_tool = tmodel.color_tool

        step_reader = STEPCAFControl_Reader()
        step_reader.SetColorMode(True)
        step_reader.SetLayerMode(True)
        step_reader.SetNameMode(True)
        step_reader.SetMatMode(True)

        status = step_reader.ReadFile(self.filename)
        if status == IFSelect_RetDone:
            logger.info("Transfer doc to STEPCAFControl_Reader")
            step_reader.Transfer(tmodel.doc)

        labels = TDF_LabelSequence()
        self.shape_tool.GetShapes(labels)
        logger.info('Number of labels at root : %i', labels.Length())
        try:
            rootlabel = labels.Value(1) # First label at root
        except RuntimeError:
            return
        name = self.getName(rootlabel)
        logger.info('Name of root label: %s', name)
        isAssy = self.shape_tool.IsAssembly(rootlabel)
        logger.info("First label at root holds an assembly? %s", isAssy)
        if isAssy:
            # If first label at root holds an assembly, it is the Top Assembly.
            # Through this label, the entire assembly is accessible.
            # there is no need to examine other labels at root explicitly.
            topLoc = TopLoc_Location()
            topLoc = self.shape_tool.GetLocation(rootlabel)
            self.assyLocStack.append(topLoc)
            entry = rootlabel.EntryDumpToString()
            logger.debug("Entry: %s", entry)
            logger.debug("Top assy name: %s", name)
            # Create root node for top assy
            newAssyUID = self.getNewUID()
            self.tree.create_node(name, newAssyUID, None,
                                  {'a': True, 'l': None, 'c': None, 's': None})
            self.assyUidStack.append(newAssyUID)
            topComps = TDF_LabelSequence() # Components of Top Assy
            subchilds = False
            isAssy = self.shape_tool.GetComponents(rootlabel, topComps, subchilds)
            logger.debug("Is Assembly? %s", isAssy)
            logger.debug("Number of components: %s", topComps.Length())
            logger.debug("Is Reference? %s", self.shape_tool.IsReference(rootlabel))
            if topComps.Length():
                self.findComponents(rootlabel, topComps)
        else:
            # Labels at root can hold solids or compounds (which are 'crude' assemblies)
            # Either way, we will need to create a root node in self.tree
            newAssyUID = self.getNewUID()
            self.tree.create_node(os.path.basename(self.filename),
                                  newAssyUID, None,
                                  {'a': True, 'l': None, 'c': None, 's': None})
            self.assyUidStack = [newAssyUID]
            for j in range(labels.Length()):
                label = labels.Value(j+1)
                name = self.getName(label)
                isAssy = self.shape_tool.IsAssembly(label)
                logger.debug("Label %i is assembly?: %s", j+1, isAssy)
                shape = self.shape_tool.GetShape(label)
                color = self.getColor(shape)
                isSimpleShape = self.shape_tool.IsSimpleShape(label)
                logger.debug("Is Simple Shape? %s", isSimpleShape)
                shapeType = shape.ShapeType()
                logger.debug("The shape type is: %i", shapeType)
                if shapeType == 0:
                    logger.debug("The shape type is OCC.Core.TopAbs.TopAbs_COMPOUND")
                    topo = TopologyExplorer(shape)
                    #topo = aocutils.topology.Topo(shape)
                    logger.debug("Nb of compounds : %i", topo.number_of_compounds())
                    logger.debug("Nb of solids : %i", topo.number_of_solids())
                    logger.debug("Nb of shells : %i", topo.number_of_shells())
                    newAssyUID = self.getNewUID()
                    for i, solid in enumerate(topo.solids()):
                        name = "P%s" % str(i+1)
                        self.tree.create_node(name, self.getNewUID(),
                                              self.assyUidStack[-1],
                                              {'a': False, 'l': None,
                                               'c': color, 's': solid})
                elif shapeType == 2:
                    logger.debug("The shape type is OCC.Core.TopAbs.TopAbs_SOLID")
                    self.tree.create_node(name, self.getNewUID(),
                                          self.assyUidStack[-1],
                                          {'a': False, 'l': None,
                                           'c': color, 's': shape})
                elif shapeType == 3:
                    logger.debug("The shape type is OCC.Core.TopAbs.TopAbs_SHELL")
                    self.tree.create_node(name, self.getNewUID(),
                                          self.assyUidStack[-1],
                                          {'a': False, 'l': None,
                                           'c': color, 's': shape})

        return tmodel.doc  # <class 'OCC.Core.TDocStd.TDocStd_Document'>
Exemplo n.º 3
0
    def read_file(self):
        """Build self.tree (treelib.Tree()) containing CAD data read from a step file.

        Each node of self.tree contains the following:
        (Name, UID, ParentUID, {Data}) where the Data keys are:
        'a' (isAssy?), 'l' (TopLoc_Location), 'c' (Quantity_Color), 's' (TopoDS_Shape)
        """
        logger.info("Reading STEP file")
        doc = TDocStd_Document(TCollection_ExtendedString("STEP"))

        # Create the application
        app = XCAFApp_Application_GetApplication()
        app.NewDocument(TCollection_ExtendedString("MDTV-CAF"), doc)

        # Get root shapes
        shape_tool = XCAFDoc_DocumentTool_ShapeTool(doc.Main())
        shape_tool.SetAutoNaming(True)
        self.color_tool = XCAFDoc_DocumentTool_ColorTool(doc.Main())
        layer_tool = XCAFDoc_DocumentTool_LayerTool(doc.Main())
        l_materials = XCAFDoc_DocumentTool_MaterialTool(doc.Main())

        step_reader = STEPCAFControl_Reader()
        step_reader.SetColorMode(True)
        step_reader.SetLayerMode(True)
        step_reader.SetNameMode(True)
        step_reader.SetMatMode(True)

        status = step_reader.ReadFile(self.filename)
        if status == IFSelect_RetDone:
            logger.info("Transfer doc to STEPCAFControl_Reader")
            step_reader.Transfer(doc)

        # Test round trip by writing doc back to another file.
        logger.info("Doing a 'short-circuit' Round Trip test")
        doctype = type(doc)  # <class 'OCC.Core.TDocStd.TDocStd_Document'>
        logger.info(f"Writing {doctype} back to another STEP file")
        self.testRTStep(doc)

        # Save doc to file (for educational purposes) (not working yet)
        logger.debug("Saving doc to file")
        savefilename = TCollection_ExtendedString('../doc.txt')
        app.SaveAs(doc, savefilename)

        labels = TDF_LabelSequence()
        color_labels = TDF_LabelSequence()

        shape_tool.GetShapes(labels)
        self.shape_tool = shape_tool
        logger.info('Number of labels at root : %i' % labels.Length())
        try:
            label = labels.Value(1)  # First label at root
        except RuntimeError:
            return
        name = self.getName(label)
        logger.info('Name of root label: %s' % name)
        isAssy = shape_tool.IsAssembly(label)
        logger.info("First label at root holds an assembly? %s" % isAssy)
        if isAssy:
            # If first label at root holds an assembly, it is the Top Assembly.
            # Through this label, the entire assembly is accessible.
            # No need to examine other labels at root explicitly.
            topLoc = TopLoc_Location()
            topLoc = shape_tool.GetLocation(label)
            self.assyLocStack.append(topLoc)
            entry = label.EntryDumpToString()
            logger.debug("Entry: %s" % entry)
            logger.debug("Top assy name: %s" % name)
            # Create root node for top assy
            newAssyUID = self.getNewUID()
            self.tree.create_node(name, newAssyUID, None, {
                'a': True,
                'l': None,
                'c': None,
                's': None
            })
            self.assyUidStack.append(newAssyUID)
            topComps = TDF_LabelSequence()  # Components of Top Assy
            subchilds = False
            isAssy = shape_tool.GetComponents(label, topComps, subchilds)
            logger.debug("Is Assembly? %s" % isAssy)
            logger.debug("Number of components: %s" % topComps.Length())
            logger.debug("Is Reference? %s" % shape_tool.IsReference(label))
            if topComps.Length():
                self.findComponents(label, topComps)
        else:
            # Labels at root can hold solids or compounds (which are 'crude' assemblies)
            # Either way, we will need to create a root node in self.tree
            newAssyUID = self.getNewUID()
            self.tree.create_node(os.path.basename(self.filename), newAssyUID,
                                  None, {
                                      'a': True,
                                      'l': None,
                                      'c': None,
                                      's': None
                                  })
            self.assyUidStack = [newAssyUID]
            for j in range(labels.Length()):
                label = labels.Value(j + 1)
                name = self.getName(label)
                isAssy = shape_tool.IsAssembly(label)
                logger.debug("Label %i is assembly?: %s" % (j + 1, isAssy))
                shape = shape_tool.GetShape(label)
                color = self.getColor(shape)
                isSimpleShape = self.shape_tool.IsSimpleShape(label)
                logger.debug("Is Simple Shape? %s" % isSimpleShape)
                shapeType = shape.ShapeType()
                logger.debug("The shape type is: %i" % shapeType)
                if shapeType == 0:
                    logger.debug(
                        "The shape type is OCC.Core.TopAbs.TopAbs_COMPOUND")
                    topo = TopologyExplorer(shape)
                    #topo = aocutils.topology.Topo(shape)
                    logger.debug("Nb of compounds : %i" %
                                 topo.number_of_compounds())
                    logger.debug("Nb of solids : %i" % topo.number_of_solids())
                    logger.debug("Nb of shells : %i" % topo.number_of_shells())
                    newAssyUID = self.getNewUID()
                    for i, solid in enumerate(topo.solids()):
                        name = "P%s" % str(i + 1)
                        self.tree.create_node(name, self.getNewUID(),
                                              self.assyUidStack[-1], {
                                                  'a': False,
                                                  'l': None,
                                                  'c': color,
                                                  's': solid
                                              })
                elif shapeType == 2:
                    logger.debug(
                        "The shape type is OCC.Core.TopAbs.TopAbs_SOLID")
                    self.tree.create_node(name, self.getNewUID(),
                                          self.assyUidStack[-1], {
                                              'a': False,
                                              'l': None,
                                              'c': color,
                                              's': shape
                                          })
                elif shapeType == 3:
                    logger.debug(
                        "The shape type is OCC.Core.TopAbs.TopAbs_SHELL")
                    self.tree.create_node(name, self.getNewUID(),
                                          self.assyUidStack[-1], {
                                              'a': False,
                                              'l': None,
                                              'c': color,
                                              's': shape
                                          })
        return True