Esempio n. 1
0
void ResultEntry::buildEntryName()
{
  ResultEntry *parentEntry = this;
  while(parentEntry->parent != 0)
  {
      ResultEntry *temp = parentEntry->parent;
      if (temp->parent == 0)
        break;
      parentEntry = parentEntry->parent;
  }

  QString stringOut;
  QTextStream stream(&stringOut);
  TopTools_IndexedMapOfShape shapeMap;
  int index(-1);

  switch (this->shape.ShapeType())
  {
  case TopAbs_COMPOUND:
      TopExp::MapShapes(parentEntry->shape, TopAbs_COMPOUND, shapeMap);
      stream << "Compound";
      break;
  case TopAbs_COMPSOLID:
      TopExp::MapShapes(parentEntry->shape, TopAbs_COMPSOLID, shapeMap);
      stream << "CompSolid";
      break;
  case TopAbs_SOLID:
      TopExp::MapShapes(parentEntry->shape, TopAbs_SOLID, shapeMap);
      stream << "Solid";
      break;
  case TopAbs_SHELL:
      TopExp::MapShapes(parentEntry->shape, TopAbs_SHELL, shapeMap);
      stream << "Shell";
      break;
  case TopAbs_WIRE:
      TopExp::MapShapes(parentEntry->shape, TopAbs_WIRE, shapeMap);
      stream << "Wire";
      break;
  case TopAbs_FACE:
      TopExp::MapShapes(parentEntry->shape, TopAbs_FACE, shapeMap);
      stream << "Face";
      break;
  case TopAbs_EDGE:
      TopExp::MapShapes(parentEntry->shape, TopAbs_EDGE, shapeMap);
      stream << "Edge";
      break;
  case TopAbs_VERTEX:
      TopExp::MapShapes(parentEntry->shape, TopAbs_VERTEX, shapeMap);
      stream << "Vertex";
      break;
  default:
      stream << "Unexpected shape type";
      break;
  }

  index = shapeMap.FindIndex(this->shape);
  stream << index;
  this->name = stringOut;
}
Esempio n. 2
0
void DlgFilletEdges::on_shapeObject_activated(int index)
{
    d->object = 0;
    QStandardItemModel *model = qobject_cast<QStandardItemModel*>(ui->treeView->model());
    model->removeRows(0, model->rowCount());

    QByteArray name = ui->shapeObject->itemData(index).toByteArray();
    App::Document* doc = App::GetApplication().getActiveDocument();
    if (!doc)
        return;
    App::DocumentObject* part = doc->getObject((const char*)name);
    if (part && part->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) {
        d->object = part;
        TopoDS_Shape myShape = static_cast<Part::Feature*>(part)->Shape.getValue();
        // build up map edge->face
        TopTools_IndexedDataMapOfShapeListOfShape edge2Face;
        TopExp::MapShapesAndAncestors(myShape, TopAbs_EDGE, TopAbs_FACE, edge2Face);
        TopTools_IndexedMapOfShape mapOfShape;
        TopExp::MapShapes(myShape, TopAbs_EDGE, mapOfShape);

        // populate the model
        d->edge_ids.clear();
        for (int i=1; i<= edge2Face.Extent(); ++i) {
            // set the index value as user data to use it in accept()
            const TopTools_ListOfShape& los = edge2Face.FindFromIndex(i);
            if (los.Extent() == 2) {
                // set the index value as user data to use it in accept()
                const TopoDS_Shape& edge = edge2Face.FindKey(i);
                // Now check also the continuity to only allow C0-continious
                // faces
                const TopoDS_Shape& face1 = los.First();
                const TopoDS_Shape& face2 = los.Last();
                GeomAbs_Shape cont = BRep_Tool::Continuity(TopoDS::Edge(edge),
                                                           TopoDS::Face(face1),
                                                           TopoDS::Face(face2));
                if (cont == GeomAbs_C0) {
                    int id = mapOfShape.FindIndex(edge);
                    d->edge_ids.push_back(id);
                }
            }
        }

        model->insertRows(0, d->edge_ids.size());
        int index = 0;
        for (std::vector<int>::iterator it = d->edge_ids.begin(); it != d->edge_ids.end(); ++it) {
            model->setData(model->index(index, 0), QVariant(tr("Edge%1").arg(*it)));
            model->setData(model->index(index, 0), QVariant(*it), Qt::UserRole);
            model->setData(model->index(index, 1), QVariant(QLocale::system().toString(1.0,'f',2)));
            model->setData(model->index(index, 2), QVariant(QLocale::system().toString(1.0,'f',2)));
            std::stringstream element;
            element << "Edge" << *it;
            if (Gui::Selection().isSelected(part, element.str().c_str()))
                model->setData(model->index(index, 0), Qt::Checked, Qt::CheckStateRole);
            else
                model->setData(model->index(index, 0), Qt::Unchecked, Qt::CheckStateRole);
            index++;
        }
    }
}
Esempio n. 3
0
QString PartGui::buildSelectionName(const ResultEntry *entry, const TopoDS_Shape &shape)
{
    const ResultEntry *parentEntry = entry;
    while(parentEntry->parent != 0)
    {
        ResultEntry *temp = parentEntry->parent;
        if (temp->parent == 0)
          break;
        parentEntry = parentEntry->parent;
    }

    QString stringOut;
    QTextStream stream(&stringOut);
    stream << parentEntry->name;
    stream << '.';
    TopTools_IndexedMapOfShape shapeMap;
    int index(-1);

    switch (shape.ShapeType())
    {
    case TopAbs_FACE:
        TopExp::MapShapes(parentEntry->shape, TopAbs_FACE, shapeMap);
        stream << "Face";
        break;
    case TopAbs_EDGE:
        TopExp::MapShapes(parentEntry->shape, TopAbs_EDGE, shapeMap);
        stream << "Edge";
        break;
    case TopAbs_VERTEX:
        TopExp::MapShapes(parentEntry->shape, TopAbs_VERTEX, shapeMap);
        stream << "Vertex";
        break;
    default:
        stream << "Unexpected shape type";
        break;
    }

    index = shapeMap.FindIndex(shape);
    stream << index;
    return stringOut;
}
QString SetupResultBase::selectionName(ResultEntry *entry, const TopoDS_Shape &shape)
{
    ResultEntry *parentEntry = entry;
    while(parentEntry->name.isEmpty())
        parentEntry = parentEntry->parent;

    QString stringOut;
    QTextStream stream(&stringOut);
    stream << parentEntry->name;
    stream << '.';
    TopTools_IndexedMapOfShape shapeMap;
    int index(-1);

    switch (shape.ShapeType())
    {
    case TopAbs_FACE:
        TopExp::MapShapes(parentEntry->shape, TopAbs_FACE, shapeMap);
        stream << "Face";
        break;
    case TopAbs_EDGE:
        TopExp::MapShapes(parentEntry->shape, TopAbs_EDGE, shapeMap);
        stream << "Edge";
        break;
    case TopAbs_VERTEX:
        TopExp::MapShapes(parentEntry->shape, TopAbs_VERTEX, shapeMap);
        stream << "Vertex";
        break;
    default:
        stream << "Unexpected shape type";
        break;
    }

    index = shapeMap.FindIndex(shape);
    stream << index;
    return stringOut;
}
Esempio n. 5
0
App::DocumentObjectExecReturn *MultiFuse::execute(void)
{
    std::vector<TopoDS_Shape> s;
    std::vector<App::DocumentObject*> obj = Shapes.getValues();

    std::vector<App::DocumentObject*>::iterator it;
    for (it = obj.begin(); it != obj.end(); ++it) {
        if ((*it)->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) {
            s.push_back(static_cast<Part::Feature*>(*it)->Shape.getValue());
        }
    }

    bool argumentsAreInCompound = false;
    TopoDS_Shape compoundOfArguments;

    //if only one source shape, and it is a compound - fuse children of the compound
    if (s.size() == 1){
        compoundOfArguments = s[0];
        if (compoundOfArguments.ShapeType() == TopAbs_COMPOUND){
            s.clear();
            TopoDS_Iterator it(compoundOfArguments);
            for (; it.More(); it.Next()) {
                const TopoDS_Shape& aChild = it.Value();
                s.push_back(aChild);
            }
            argumentsAreInCompound = true;
        }
    }

    if (s.size() >= 2) {
        try {
            std::vector<ShapeHistory> history;
#if OCC_VERSION_HEX <= 0x060800
            TopoDS_Shape resShape = s.front();
            if (resShape.IsNull())
                throw Base::Exception("Input shape is null");
            for (std::vector<TopoDS_Shape>::iterator it = s.begin()+1; it != s.end(); ++it) {
                if (it->IsNull())
                    throw Base::Exception("Input shape is null");

                // Let's call algorithm computing a fuse operation:
                BRepAlgoAPI_Fuse mkFuse(resShape, *it);
                // Let's check if the fusion has been successful
                if (!mkFuse.IsDone()) 
                    throw Base::Exception("Fusion failed");
                resShape = mkFuse.Shape();

                ShapeHistory hist1 = buildHistory(mkFuse, TopAbs_FACE, resShape, mkFuse.Shape1());
                ShapeHistory hist2 = buildHistory(mkFuse, TopAbs_FACE, resShape, mkFuse.Shape2());
                if (history.empty()) {
                    history.push_back(hist1);
                    history.push_back(hist2);
                }
                else {
                    for (std::vector<ShapeHistory>::iterator jt = history.begin(); jt != history.end(); ++jt)
                        *jt = joinHistory(*jt, hist1);
                    history.push_back(hist2);
                }
            }
#else
            BRepAlgoAPI_Fuse mkFuse;
            TopTools_ListOfShape shapeArguments,shapeTools;
            shapeArguments.Append(s.front());
            for (std::vector<TopoDS_Shape>::iterator it = s.begin()+1; it != s.end(); ++it) {
                if (it->IsNull())
                    throw Base::Exception("Input shape is null");
                shapeTools.Append(*it);
            }
            mkFuse.SetArguments(shapeArguments);
            mkFuse.SetTools(shapeTools);
            mkFuse.Build();
            if (!mkFuse.IsDone())
                throw Base::Exception("MultiFusion failed");
            TopoDS_Shape resShape = mkFuse.Shape();
            for (std::vector<TopoDS_Shape>::iterator it = s.begin(); it != s.end(); ++it) {
                history.push_back(buildHistory(mkFuse, TopAbs_FACE, resShape, *it));
            }
#endif
            if (resShape.IsNull())
                throw Base::Exception("Resulting shape is null");

            Base::Reference<ParameterGrp> hGrp = App::GetApplication().GetUserParameter()
                .GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/Part/Boolean");
            if (hGrp->GetBool("CheckModel", false)) {
                BRepCheck_Analyzer aChecker(resShape);
                if (! aChecker.IsValid() ) {
                    return new App::DocumentObjectExecReturn("Resulting shape is invalid");
                }
            }
            if (hGrp->GetBool("RefineModel", false)) {
                try {
                    TopoDS_Shape oldShape = resShape;
                    BRepBuilderAPI_RefineModel mkRefine(oldShape);
                    resShape = mkRefine.Shape();
                    ShapeHistory hist = buildHistory(mkRefine, TopAbs_FACE, resShape, oldShape);
                    for (std::vector<ShapeHistory>::iterator jt = history.begin(); jt != history.end(); ++jt)
                        *jt = joinHistory(*jt, hist);
                }
                catch (Standard_Failure) {
                    // do nothing
                }
            }

            this->Shape.setValue(resShape);


            if (argumentsAreInCompound){
                //combine histories of every child of source compound into one
                ShapeHistory overallHist;
                TopTools_IndexedMapOfShape facesOfCompound;
                TopAbs_ShapeEnum type = TopAbs_FACE;
                TopExp::MapShapes(compoundOfArguments, type, facesOfCompound);
                for (std::size_t iChild = 0; iChild < history.size(); iChild++){ //loop over children of source compound
                    //for each face of a child, find the inex of the face in compound, and assign the corresponding right-hand-size of the history
                    TopTools_IndexedMapOfShape facesOfChild;
                    TopExp::MapShapes(s[iChild], type, facesOfChild);
                    for(std::pair<const int,ShapeHistory::List> &histitem: history[iChild].shapeMap){ //loop over elements of history - that is - over faces of the child of source compound
                        int iFaceInChild = histitem.first;
                        ShapeHistory::List &iFacesInResult = histitem.second;
                        TopoDS_Shape srcFace = facesOfChild(iFaceInChild + 1); //+1 to convert our 0-based to OCC 1-bsed conventions
                        int iFaceInCompound = facesOfCompound.FindIndex(srcFace)-1;
                        overallHist.shapeMap[iFaceInCompound] = iFacesInResult; //this may overwrite existing info if the same face is used in several children of compound. This shouldn't be a problem, because the histories should match anyway...
                    }
                }
                history.clear();
                history.push_back(overallHist);
            }
            this->History.setValues(history);
        }
        catch (Standard_Failure& e) {
            return new App::DocumentObjectExecReturn(e.GetMessageString());
        }
    }
    else {
        throw Base::Exception("Not enough shape objects linked");
    }

    return App::DocumentObject::StdReturn;
}
void NETGENPlugin_Mesher::PrepareOCCgeometry(netgen::OCCGeometry&     occgeo,
                                             const TopoDS_Shape&      shape,
                                             SMESH_Mesh&              mesh,
                                             list< SMESH_subMesh* > * meshedSM)
{
  BRepTools::Clean (shape);
  try {
#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
    OCC_CATCH_SIGNALS;
#endif
    BRepMesh_IncrementalMesh::BRepMesh_IncrementalMesh (shape, 0.01, true);
  } catch (Standard_Failure) {
  }
  Bnd_Box bb;
  BRepBndLib::Add (shape, bb);
  double x1,y1,z1,x2,y2,z2;
  bb.Get (x1,y1,z1,x2,y2,z2);
  MESSAGE("shape bounding box:\n" <<
          "(" << x1 << " " << y1 << " " << z1 << ") " <<
          "(" << x2 << " " << y2 << " " << z2 << ")");
  netgen::Point<3> p1 = netgen::Point<3> (x1,y1,z1);
  netgen::Point<3> p2 = netgen::Point<3> (x2,y2,z2);
  occgeo.boundingbox = netgen::Box<3> (p1,p2);

  occgeo.shape = shape;
  occgeo.changed = 1;
  //occgeo.BuildFMap();

  // fill maps of shapes of occgeo with not yet meshed subshapes

  // get root submeshes
  list< SMESH_subMesh* > rootSM;
  if ( SMESH_subMesh* sm = mesh.GetSubMeshContaining( shape )) {
    rootSM.push_back( sm );
  }
  else {
    for ( TopoDS_Iterator it( shape ); it.More(); it.Next() )
      rootSM.push_back( mesh.GetSubMesh( it.Value() ));
  }

  // add subshapes of empty submeshes
  list< SMESH_subMesh* >::iterator rootIt = rootSM.begin(), rootEnd = rootSM.end();
  for ( ; rootIt != rootEnd; ++rootIt ) {
    SMESH_subMesh * root = *rootIt;
    SMESH_subMeshIteratorPtr smIt = root->getDependsOnIterator(/*includeSelf=*/true,
                                                               /*complexShapeFirst=*/true);
    // to find a right orientation of subshapes (PAL20462)
    TopTools_IndexedMapOfShape subShapes;
    TopExp::MapShapes(root->GetSubShape(), subShapes);
    while ( smIt->more() ) {
      SMESH_subMesh* sm = smIt->next();
      if ( !meshedSM || sm->IsEmpty() ) {
        TopoDS_Shape shape = sm->GetSubShape();
        if ( shape.ShapeType() != TopAbs_VERTEX )
          shape = subShapes( subShapes.FindIndex( shape ));// - shape->index->oriented shape
        switch ( shape.ShapeType() ) {
        case TopAbs_FACE  : occgeo.fmap.Add( shape ); break;
        case TopAbs_EDGE  : occgeo.emap.Add( shape ); break;
        case TopAbs_VERTEX: occgeo.vmap.Add( shape ); break;
        case TopAbs_SOLID :occgeo.somap.Add( shape ); break;
        default:;
        }
      }
      // collect submeshes of meshed shapes
      else if (meshedSM) {
        meshedSM->push_back( sm );
      }
    }
  }
  occgeo.facemeshstatus.SetSize (occgeo.fmap.Extent());
  occgeo.facemeshstatus = 0;

}
Esempio n. 7
0
int OCCWire::chamfer(std::vector<OCCVertex *> vertices, std::vector<double> distances) {
    int vertices_size = vertices.size();
    int distances_size = distances.size();
    
    BRepFilletAPI_MakeFillet2d MF;
    try {
        if (this->getShape().IsNull()) {
            StdFail_NotDone::Raise("Shapes is Null");
        }
        
        MF.Init(BRepBuilderAPI_MakeFace(this->getWire()));
        
        // creat map of vertices
        TopTools_IndexedMapOfShape vertMap;
        for (unsigned i=0; i<vertices.size(); i++)
            vertMap.Add(vertices[i]->getShape());
        
        bool first = true;
        TopoDS_Edge firstEdge, nextEdge;
        TopoDS_Vertex vertex;
        
        BRepTools_WireExplorer Ex1;
        for (Ex1.Init(this->getWire()); Ex1.More(); ) {
            if(first == true) {
                firstEdge = Ex1.Current();
                first = false;                                                    
            }

            Ex1.Next();
            
            //if the number of edges is odd don't proceed
            if(Ex1.More() == Standard_False)     
                break;
            
            nextEdge = Ex1.Current();
            
            //get the common vertex of the two edges
            if (!TopExp::CommonVertex(firstEdge, nextEdge, vertex)) {
                // disconnected wire
                first = true;
                continue;
            }
            
            if (vertMap.Contains(vertex)) {
                int i = vertMap.FindIndex(vertex) - 1;
                
                if (distances_size == 1) {
                    // single distance
                    MF.AddChamfer(firstEdge, nextEdge, distances[0], distances[0]);
                } else if (distances_size == vertices_size) {
                    // distance given for each vertex
                    MF.AddChamfer(firstEdge, nextEdge, distances[i], distances[i]);
                } else {
                    StdFail_NotDone::Raise("distances argument has wrong size");
                }
            
            }
            
            firstEdge = nextEdge;
        }
        
        // special case for closed wire
        if (isClosed()) {
            // find seam vertex
            TopoDS_Vertex aV1;
            TopExp::Vertices(this->getWire(), vertex, aV1);
            
            // check if seam vertex has chamfer value
            if (vertMap.Contains(vertex)) {
                int i = vertMap.FindIndex(vertex) - 1;
                
                // map vertices to edges to find edge pair
                TopTools_IndexedDataMapOfShapeListOfShape mapVertexEdge;
                TopExp::MapShapesAndAncestors(this->getWire(), TopAbs_VERTEX, TopAbs_EDGE, mapVertexEdge);
                
                const TopTools_ListOfShape& edges = mapVertexEdge.FindFromKey(vertex);
                firstEdge = TopoDS::Edge(edges.First());
                nextEdge = TopoDS::Edge(edges.Last());
                
                if (distances_size == 1) {
                    // single distance
                    MF.AddChamfer(firstEdge, nextEdge, distances[0], distances[0]);
                } else if (distances_size == vertices_size) {
                    // distance given for each vertex
                    MF.AddChamfer(firstEdge, nextEdge, distances[i], distances[i]);
                } else {
                    StdFail_NotDone::Raise("distances argument has wrong size");
                }
            }
        }
        
        if(MF.Status() != ChFi2d_IsDone)
            StdFail_NotDone::Raise("chamfer operation failed");
        
        TopTools_IndexedMapOfShape aMap;
        TopExp::MapShapes(MF.Shape(), TopAbs_WIRE, aMap);
        if(aMap.Extent() != 1)
            StdFail_NotDone::Raise("chamfer result did not result in single wire");;
        
        //add edges to the wire
        BRepBuilderAPI_MakeWire wire;
        BRepTools_WireExplorer Ex2;
        for(Ex2.Init(TopoDS::Wire(aMap(1))); Ex2.More(); Ex2.Next())
        {
            wire.Add(Ex2.Current());
        }
          
        this->setShape(wire.Shape());
        
        // possible fix shape
        if (!this->fixShape())
            StdFail_NotDone::Raise("Shapes not valid");
        
    } catch(Standard_Failure &err) {
        Handle_Standard_Failure e = Standard_Failure::Caught();
        const Standard_CString msg = e->GetMessageString();
        if (msg != NULL && strlen(msg) > 1) {
            setErrorMessage(msg);
        } else {
            setErrorMessage("Failed to chamfer wire");
        }
        return 0;
    }
    return 1;
}
Esempio n. 8
0
void ViewProviderPartExt::updateVisual(const TopoDS_Shape& inputShape)
{
    // Clear selection
    Gui::SoSelectionElementAction action(Gui::SoSelectionElementAction::None);
    action.apply(this->faceset);
    action.apply(this->lineset);
    action.apply(this->nodeset);

    TopoDS_Shape cShape(inputShape);
    if (cShape.IsNull()) {
        coords  ->point      .setNum(0);
        norm    ->vector     .setNum(0);
        faceset ->coordIndex .setNum(0);
        faceset ->partIndex  .setNum(0);
        lineset ->coordIndex .setNum(0);
        VisualTouched = false;
        return;
    }

    // time measurement and book keeping
    Base::TimeInfo start_time;
    int nbrTriangles=0,nbrNodes=0,nbrNorms=0,nbrFaces=0,nbrEdges=0,nbrLines=0;
    std::set<int> faceEdges;

    try {
        // calculating the deflection value
        Bnd_Box bounds;
        BRepBndLib::Add(cShape, bounds);
        bounds.SetGap(0.0);
        Standard_Real xMin, yMin, zMin, xMax, yMax, zMax;
        bounds.Get(xMin, yMin, zMin, xMax, yMax, zMax);
        Standard_Real deflection = ((xMax-xMin)+(yMax-yMin)+(zMax-zMin))/300.0 *
            Deviation.getValue();

        // create or use the mesh on the data structure
        BRepMesh_IncrementalMesh myMesh(cShape,deflection);
        // We must reset the location here because the transformation data
        // are set in the placement property
        TopLoc_Location aLoc;
        cShape.Location(aLoc);

        // count triangles and nodes in the mesh
        TopExp_Explorer Ex;
        for (Ex.Init(cShape,TopAbs_FACE);Ex.More();Ex.Next()) {
            Handle (Poly_Triangulation) mesh = BRep_Tool::Triangulation(TopoDS::Face(Ex.Current()), aLoc);
            // Note: we must also count empty faces
            if (!mesh.IsNull()) {
                nbrTriangles += mesh->NbTriangles();
                nbrNodes     += mesh->NbNodes();
                nbrNorms     += mesh->NbNodes();
            }

            TopExp_Explorer xp;
            for (xp.Init(Ex.Current(),TopAbs_EDGE);xp.More();xp.Next())
                faceEdges.insert(xp.Current().HashCode(INT_MAX));
            nbrFaces++;
        }

        // get an indexed map of edges
        TopTools_IndexedMapOfShape M;
        TopExp::MapShapes(cShape, TopAbs_EDGE, M);

        std::set<int>         edgeIdxSet;
        std::vector<int32_t>  indxVector;
        std::vector<int32_t>  edgeVector;

        // count and index the edges
        for (int i=1; i <= M.Extent(); i++) {
            edgeIdxSet.insert(i);
            nbrEdges++;

            const TopoDS_Edge& aEdge = TopoDS::Edge(M(i));
            TopLoc_Location aLoc;

            // handling of the free edge that are not associated to a face
            // Note: The assumption that if for an edge BRep_Tool::Polygon3D
            // returns a valid object is wrong. This e.g. happens for ruled
            // surfaces which gets created by two edges or wires.
            // So, we have to store the hashes of the edges associated to a face.
            // If the hash of a given edge is not in this list we know it's really
            // a free edge.
            int hash = aEdge.HashCode(INT_MAX);
            if (faceEdges.find(hash) == faceEdges.end()) {
                Handle(Poly_Polygon3D) aPoly = BRep_Tool::Polygon3D(aEdge, aLoc);
                if (!aPoly.IsNull()) {
                    int nbNodesInEdge = aPoly->NbNodes();
                    nbrNodes += nbNodesInEdge;
                }
            }
        }
        // reserve some memory
        indxVector.reserve(nbrEdges*8);

        // handling of the vertices
        TopTools_IndexedMapOfShape V;
        TopExp::MapShapes(cShape, TopAbs_VERTEX, V);
        nbrNodes += V.Extent();

        // create memory for the nodes and indexes
        coords  ->point      .setNum(nbrNodes);
        norm    ->vector     .setNum(nbrNorms);
        faceset ->coordIndex .setNum(nbrTriangles*4);
        faceset ->partIndex  .setNum(nbrFaces);
        // get the raw memory for fast fill up
        SbVec3f* verts = coords  ->point       .startEditing();
        SbVec3f* norms = norm    ->vector      .startEditing();
        int32_t* index = faceset ->coordIndex  .startEditing();
        int32_t* parts = faceset ->partIndex   .startEditing();

        // preset the normal vector with null vector
        for (int i=0;i < nbrNorms;i++) 
            norms[i]= SbVec3f(0.0,0.0,0.0);

        int ii = 0,FaceNodeOffset=0,FaceTriaOffset=0;
        for (Ex.Init(cShape, TopAbs_FACE); Ex.More(); Ex.Next(),ii++) {
            TopLoc_Location aLoc;
            const TopoDS_Face &actFace = TopoDS::Face(Ex.Current());
            // get the mesh of the shape
            Handle (Poly_Triangulation) mesh = BRep_Tool::Triangulation(actFace,aLoc);
            if (mesh.IsNull()) continue;

            // getting the transformation of the shape/face
            gp_Trsf myTransf;
            Standard_Boolean identity = true;
            if (!aLoc.IsIdentity()) {
                identity = false;
                myTransf = aLoc.Transformation();
            }

            // getting size of node and triangle array of this face
            int nbNodesInFace = mesh->NbNodes();
            int nbTriInFace   = mesh->NbTriangles();
            // check orientation
            TopAbs_Orientation orient = actFace.Orientation();


            // cycling through the poly mesh
            const Poly_Array1OfTriangle& Triangles = mesh->Triangles();
            const TColgp_Array1OfPnt& Nodes = mesh->Nodes();
            for (int g=1;g<=nbTriInFace;g++) {
                // Get the triangle
                Standard_Integer N1,N2,N3;
                Triangles(g).Get(N1,N2,N3);

                // change orientation of the triangle if the face is reversed
                if ( orient != TopAbs_FORWARD ) {
                    Standard_Integer tmp = N1;
                    N1 = N2;
                    N2 = tmp;
                }

                // get the 3 points of this triangle
                gp_Pnt V1(Nodes(N1)), V2(Nodes(N2)), V3(Nodes(N3));

                // transform the vertices to the place of the face
                if (!identity) {
                    V1.Transform(myTransf);
                    V2.Transform(myTransf);
                    V3.Transform(myTransf);
                }
                
                // calculating per vertex normals                    
                // Calculate triangle normal
                gp_Vec v1(V1.X(),V1.Y(),V1.Z()),v2(V2.X(),V2.Y(),V2.Z()),v3(V3.X(),V3.Y(),V3.Z());
                gp_Vec Normal = (v2-v1)^(v3-v1); 

                // add the triangle normal to the vertex normal for all points of this triangle
                norms[FaceNodeOffset+N1-1] += SbVec3f(Normal.X(),Normal.Y(),Normal.Z());
                norms[FaceNodeOffset+N2-1] += SbVec3f(Normal.X(),Normal.Y(),Normal.Z());
                norms[FaceNodeOffset+N3-1] += SbVec3f(Normal.X(),Normal.Y(),Normal.Z());                 

                // set the vertices
                verts[FaceNodeOffset+N1-1].setValue((float)(V1.X()),(float)(V1.Y()),(float)(V1.Z()));
                verts[FaceNodeOffset+N2-1].setValue((float)(V2.X()),(float)(V2.Y()),(float)(V2.Z()));
                verts[FaceNodeOffset+N3-1].setValue((float)(V3.X()),(float)(V3.Y()),(float)(V3.Z()));

                // set the index vector with the 3 point indexes and the end delimiter
                index[FaceTriaOffset*4+4*(g-1)]   = FaceNodeOffset+N1-1; 
                index[FaceTriaOffset*4+4*(g-1)+1] = FaceNodeOffset+N2-1; 
                index[FaceTriaOffset*4+4*(g-1)+2] = FaceNodeOffset+N3-1; 
                index[FaceTriaOffset*4+4*(g-1)+3] = SO_END_FACE_INDEX;
            }

            parts[ii] = nbTriInFace; // new part

            // handling the edges lying on this face
            TopExp_Explorer Exp;
            for(Exp.Init(actFace,TopAbs_EDGE);Exp.More();Exp.Next()) {
                const TopoDS_Edge &actEdge = TopoDS::Edge(Exp.Current());
                // get the overall index of this edge
                int idx = M.FindIndex(actEdge);
                edgeVector.push_back((int32_t)idx-1);
                // already processed this index ?
                if (edgeIdxSet.find(idx)!=edgeIdxSet.end()) {
                    
                    // this holds the indices of the edge's triangulation to the current polygon
                    Handle(Poly_PolygonOnTriangulation) aPoly = BRep_Tool::PolygonOnTriangulation(actEdge, mesh, aLoc);
                    if (aPoly.IsNull())
                        continue; // polygon does not exist
                    
                    // getting the indexes of the edge polygon
                    const TColStd_Array1OfInteger& indices = aPoly->Nodes();
                    for (Standard_Integer i=indices.Lower();i <= indices.Upper();i++) {
                        int inx = indices(i);
                        indxVector.push_back(FaceNodeOffset+inx-1);

                        // usually the coordinates for this edge are already set by the
                        // triangles of the face this edge belongs to. However, there are
                        // rare cases where some points are only referenced by the polygon
                        // but not by any triangle. Thus, we must apply the coordinates to
                        // make sure that everything is properly set.
                        gp_Pnt p(Nodes(inx));
                        if (!identity)
                            p.Transform(myTransf);
                        verts[FaceNodeOffset+inx-1].setValue((float)(p.X()),(float)(p.Y()),(float)(p.Z()));
                    }
                    indxVector.push_back(-1);

                    // remove the handled edge index from the set
                    edgeIdxSet.erase(idx);
                }
            }

            edgeVector.push_back(-1);
            
            // counting up the per Face offsets
            FaceNodeOffset += nbNodesInFace;
            FaceTriaOffset += nbTriInFace;
        }

        // handling of the free edges
        for (int i=1; i <= M.Extent(); i++) {
            const TopoDS_Edge& aEdge = TopoDS::Edge(M(i));
            Standard_Boolean identity = true;
            gp_Trsf myTransf;
            TopLoc_Location aLoc;

            // handling of the free edge that are not associated to a face
            int hash = aEdge.HashCode(INT_MAX);
            if (faceEdges.find(hash) == faceEdges.end()) {
                Handle(Poly_Polygon3D) aPoly = BRep_Tool::Polygon3D(aEdge, aLoc);
                if (!aPoly.IsNull()) {
                    if (!aLoc.IsIdentity()) {
                        identity = false;
                        myTransf = aLoc.Transformation();
                    }

                    const TColgp_Array1OfPnt& aNodes = aPoly->Nodes();
                    int nbNodesInEdge = aPoly->NbNodes();

                    gp_Pnt pnt;
                    for (Standard_Integer j=1;j <= nbNodesInEdge;j++) {
                        pnt = aNodes(j);
                        if (!identity)
                            pnt.Transform(myTransf);
                        verts[FaceNodeOffset+j-1].setValue((float)(pnt.X()),(float)(pnt.Y()),(float)(pnt.Z()));
                        indxVector.push_back(FaceNodeOffset+j-1);
                    }

                    indxVector.push_back(-1);
                    FaceNodeOffset += nbNodesInEdge;
                }
            }
        }

        nodeset->startIndex.setValue(FaceNodeOffset);
        for (int i=0; i<V.Extent(); i++) {
            const TopoDS_Vertex& aVertex = TopoDS::Vertex(V(i+1));
            gp_Pnt pnt = BRep_Tool::Pnt(aVertex);
            verts[FaceNodeOffset+i].setValue((float)(pnt.X()),(float)(pnt.Y()),(float)(pnt.Z()));
        }

        // normalize all normals 
        for (int i = 0; i< nbrNorms ;i++)
            norms[i].normalize();
        
        // preset the index vector size
        nbrLines =  indxVector.size();
        lineset ->coordIndex .setNum(nbrLines);
        int32_t* lines = lineset ->coordIndex  .startEditing();

        int l=0;
        for (std::vector<int32_t>::const_iterator it=indxVector.begin();it!=indxVector.end();++it,l++)
            lines[l] = *it;

        // end the editing of the nodes
        coords  ->point       .finishEditing();
        norm    ->vector      .finishEditing();
        faceset ->coordIndex  .finishEditing();
        faceset ->partIndex   .finishEditing();
        lineset ->coordIndex  .finishEditing();
    }
    catch (...) {
        Base::Console().Error("Cannot compute Inventor representation for the shape of %s.\n",pcObject->getNameInDocument());
    }

    // printing some informations
    Base::Console().Log("ViewProvider update time: %f s\n",Base::TimeInfo::diffTimeF(start_time,Base::TimeInfo()));
    Base::Console().Log("Shape tria info: Faces:%d Edges:%d Nodes:%d Triangles:%d IdxVec:%d\n",nbrFaces,nbrEdges,nbrNodes,nbrTriangles,nbrLines);

    VisualTouched = false;
}
Esempio n. 9
0
void CreateFacesAndEdges(TopoDS_Shape shape, CFaceList* faces, CEdgeList* edges, CVertexList* vertices)
{
	// create index maps
	TopTools_IndexedMapOfShape faceMap;
	TopTools_IndexedMapOfShape edgeMap;
	TopTools_IndexedMapOfShape vertexMap;
	for (TopExp_Explorer explorer(shape, TopAbs_FACE); explorer.More(); explorer.Next())
	{
		faceMap.Add(explorer.Current());
	}
	for (TopExp_Explorer explorer(shape, TopAbs_EDGE); explorer.More(); explorer.Next())
	{
		edgeMap.Add(explorer.Current());
	}
	for (TopExp_Explorer explorer(shape, TopAbs_VERTEX); explorer.More(); explorer.Next())
	{
		vertexMap.Add(explorer.Current());
	}

	std::vector<CFace*> face_array;
	face_array.resize(faceMap.Extent() + 1);
	std::vector<CEdge*> edge_array;
	edge_array.resize(edgeMap.Extent() + 1);
	std::vector<CVertex*> vertex_array;
	vertex_array.resize(vertexMap.Extent() + 1);

	// create the edge objects
	for(int i = 1;i<=edgeMap.Extent();i++)
	{
		const TopoDS_Shape &s = edgeMap(i);
		CEdge* new_object = new CEdge(TopoDS::Edge(s));
		edge_array[i] = new_object;
	}

	// create the vertex objects
	for(int i = 1;i<=vertexMap.Extent();i++)
	{
		const TopoDS_Shape &s = vertexMap(i);
		CVertex* new_object = new CVertex(TopoDS::Vertex(s));
		vertex_array[i] = new_object;
	}

	// add the edges in their face loop order
	std::set<CEdge*> edges_added;
	std::set<CVertex*> vertices_added;

	// create the face objects
	for(int i = 1;i<=faceMap.Extent();i++)
	{
		const TopoDS_Shape &s = faceMap(i);
		CFace* new_face_object = new CFace(TopoDS::Face(s));
		faces->Add(new_face_object, NULL);
		face_array[i] = new_face_object;

		// create the loop objects
		TopTools_IndexedMapOfShape loopMap;
		for (TopExp_Explorer explorer(s, TopAbs_WIRE); explorer.More(); explorer.Next())
		{
			loopMap.Add(explorer.Current());
		}
		TopoDS_Wire outerWire=BRepTools::OuterWire(new_face_object->Face());
		int outer_index = loopMap.FindIndex(outerWire);
		for(int i = 1;i<=loopMap.Extent();i++)
		{
			const TopoDS_Shape &s = loopMap(i);
			CLoop* new_loop_object = new CLoop(TopoDS::Wire(s));
			new_face_object->m_loops.push_back(new_loop_object);
			if(outer_index == i)new_loop_object->m_is_outer = true;
			new_loop_object->m_pface = new_face_object;

			// find the loop's edges
			for(BRepTools_WireExplorer explorer(TopoDS::Wire(s)); explorer.More(); explorer.Next())
			{
				CEdge* e = edge_array[edgeMap.FindIndex(explorer.Current())];
				new_loop_object->m_edges.push_back(e);

				// add the edge
				if(edges_added.find(e) == edges_added.end())
				{
					edges->Add(e, NULL);
					edges_added.insert(e);
				}

				// add the vertex
				CVertex* v = vertex_array[vertexMap.FindIndex(explorer.CurrentVertex())];
				if(vertices_added.find(v) == vertices_added.end())
				{
					vertices->Add(v, NULL);
					vertices_added.insert(v);
				}
			}
		}
	}

	// find the vertices' edges
	for(unsigned int i = 1; i<vertex_array.size(); i++)
	{
		CVertex* v = vertex_array[i];
		TopTools_IndexedMapOfShape vertexEdgeMap;
		for (TopExp_Explorer expEdge(v->Vertex(), TopAbs_EDGE); expEdge.More(); expEdge.Next())
		{
			vertexEdgeMap.Add(expEdge.Current());
		}
		for(int i = 1; i<=vertexEdgeMap.Extent(); i++)
		{
			const TopoDS_Shape &s = vertexEdgeMap(i);
			CEdge* e = edge_array[edgeMap.FindIndex(s)];
			v->m_edges.push_back(e);
		}
	}

	// find the faces' edges
	for(unsigned int i = 1; i<face_array.size(); i++)
	{
		CFace* face = face_array[i];
		TopTools_IndexedMapOfShape faceEdgeMap;
		for (TopExp_Explorer expEdge(face->Face(), TopAbs_EDGE); expEdge.More(); expEdge.Next())
		{
			faceEdgeMap.Add(expEdge.Current());
		}
		for(int i = 1; i<=faceEdgeMap.Extent(); i++)
		{
			const TopoDS_Shape &s = faceEdgeMap(i);
			CEdge* e = edge_array[edgeMap.FindIndex(s)];
			face->m_edges.push_back(e);
			e->m_faces.push_back(face);
			bool sense = (s.IsEqual(e->Edge()) == Standard_True);
			e->m_face_senses.push_back(sense);
		}
	}
}
Esempio n. 10
0
void OCC_Connect::FaceCutters::Build(TopoDS_Face const &face,
    TopoDS_Shape &result, int verbose)
{
    clear();

    /* First we create some data structures to access the topology */
    TopTools_IndexedMapOfShape vertices;
    std::vector<std::pair<int,int> > e2v;
    for(unsigned int i = 0; i < edges.size(); i++) {
        TopExp::MapShapes(edges[i],TopAbs_VERTEX,vertices);
        TopoDS_Vertex v1, v2;
        TopExp::Vertices(edges[i],v1,v2);
        std::pair<int,int> t(vertices.FindIndex(v1),vertices.FindIndex(v2));
        e2v.push_back(t);
    }

    std::vector<std::set<int> > v2e;
    for(unsigned int e = 0; e < e2v.size(); e++) {
      if(e2v[e].first >= (int)v2e.size())
            v2e.resize(e2v[e].first+1);
        v2e[e2v[e].first].insert(e);
        if(e2v[e].second >= (int)v2e.size())
            v2e.resize(e2v[e].second+1);
        v2e[e2v[e].second].insert(e);
    }

    std::set<int> open, odd;
    for(unsigned int i = 0; i < v2e.size(); i++) {
        if(v2e[i].size()==0)
            continue;
        else if(v2e[i].size()==1)
            open.insert(i);
        else if(v2e[i].size()&1)
            odd.insert(i);
    }

    if(open.size()&1)
        std::cerr << "Inconsistent open loops\n";
    if(odd.size()&1)
        std::cerr << "Inconsistent odd loops\n";

    for(;;) {
        int open_mode = -1;
        std::set<int> current_vertices;
        for(unsigned int start = 0; start < v2e.size(); start++) {
            if(v2e[start].size()==1) {
                if(verbose&Cutting)
                  std::cout << "start open at " << start << "\n";
                current_vertices.insert(start);
                open_mode=1;
                break;
            }
        }
        if(!current_vertices.size()) {
            for(unsigned int start = 0; start < v2e.size(); start++) {
                if(v2e[start].size()) {
                    if(verbose&Cutting)
                      std::cout << "start closed at " << start << "\n";
                    current_vertices.insert(start);
                    open_mode=0;
                    break;
                }
            }
        }
        if(!current_vertices.size())
            break;

        std::map<int,std::deque<int> > wires;
        std::set<int> processed_edges;
        do {
            std::set<int> next_vertices;
            for(std::set<int>::iterator v=current_vertices.begin();
                v!=current_vertices.end();
                v++
            ) {
                for(std::set<int>::iterator e=v2e[*v].begin() ;
                    e!=v2e[*v].end();
                    e++
                ) {
                    if(processed_edges.count(*e))
                        continue;

                    int other=e2v[*e].first==*v?
                        e2v[*e].second:e2v[*e].first;

                    if(open_mode) {
                        if(v2e[other].size()==1) {
                            // Other is open end too, finish wire.
                            wires[*v].push_back(*e);
                            std::deque<int>::const_iterator p;
                            BRepBuilderAPI_MakeWire wire;
                            if(verbose&Cutting)
                                std::cout << "CUT Open wire:";
                            for(p=wires[*v].begin();
                                p!=wires[*v].end();
                                p++
                            ) {
                                FinishEdge(*p, v2e, e2v);
                                wire.Add(edges[*p]);
                                if(verbose&Cutting)
                                    std::cout << ' ' << (*p)+1;
                            }
                            if(verbose&Cutting)
                                std::cout << "\n";
                            push_back(wire);
                            goto next_vertex;
                        }
                    } else {
                        if( current_vertices.count(other) ||
                            next_vertices.count(other)
                        ) {
                            if(verbose&Cutting)
                                std::cout << "CUT Closed wire:";
                            wires[*v].push_back(*e);
                            while(wires[other].front()
                                ==wires[*v].front()
                            ) {
                                wires[other].pop_front();
                                wires[*v].pop_front();
                            }

                            BRepBuilderAPI_MakeWire wire;
                            std::deque<int>::const_iterator p;
                            for(p=wires[other].begin();
                                p!=wires[other].end();
                                p++
                            ) {
                                FinishEdge(*p, v2e, e2v);
                                wire.Add(edges[*p]);
                                if(verbose&Cutting)
                                    std::cout << ' ' << (*p)+1;
                            }
                            std::deque<int>::reverse_iterator rp;
                            for(rp=wires[*v].rbegin();
                                rp!=wires[*v].rend();
                                rp++
                            ) {
                                FinishEdge(*rp, v2e, e2v);
                                wire.Add(edges[*rp]);
                                if(verbose&Cutting)
                                    std::cout << ' ' << (*rp)+1;
                            }
                            if(verbose&Cutting)
                                std::cout << "\n";
                            push_back(wire);
                            goto next_vertex;
                        }
                    }
                    if(current_vertices.count(other)==0) {
                        wires[other]=wires[*v];
                        wires[other].push_back(*e);
                        processed_edges.insert(*e);
                        next_vertices.insert(other);
                    }
                }
            }
            current_vertices=next_vertices;
        } while(current_vertices.size());
        next_vertex: ;
    }

    if(size()>1 && verbose&CuttingIntermediate) {
        if(verbose&Cutting)
            std::cout << "Saving multiple cuts\n";
        BRep_Builder BB;
        TopoDS_Compound compound;
        BB.MakeCompound(compound);
        for(unsigned int i = 0; i < edges.size(); i++)
            BB.Add(compound,edges[i]);
        BRepTools::Write(compound,"cutter.brep");
        ofstream out("cutter.dot",ios::trunc|ios::out);
        dump(e2v,out);
    }
}
Esempio n. 11
0
void CmdPartDesignChamfer::activated(int iMsg)
{
    std::vector<Gui::SelectionObject> selection = getSelection().getSelectionEx();

    if (selection.size() != 1) {
        QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
            QObject::tr("Select an edge, face or body. Only one body is allowed."));
        return;
    }

    if (!selection[0].isObjectTypeOf(Part::Feature::getClassTypeId())){
        QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong object type"),
            QObject::tr("Chamfer works only on parts"));
        return;
    }

    Part::Feature *base = static_cast<Part::Feature*>(selection[0].getObject());

    const Part::TopoShape& TopShape = base->Shape.getShape();

    if (TopShape._Shape.IsNull()){
        QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
            QObject::tr("Shape of selected part is empty"));
        return;
    }

    TopTools_IndexedMapOfShape mapOfEdges;
    TopTools_IndexedDataMapOfShapeListOfShape mapEdgeFace;
    TopExp::MapShapesAndAncestors(TopShape._Shape, TopAbs_EDGE, TopAbs_FACE, mapEdgeFace);
    TopExp::MapShapes(TopShape._Shape, TopAbs_EDGE, mapOfEdges);

    std::vector<std::string> SubNames = std::vector<std::string>(selection[0].getSubNames());

    int i = 0;

    while(i < SubNames.size())
    {
        std::string aSubName = static_cast<std::string>(SubNames.at(i));

        if (aSubName.size() > 4 && aSubName.substr(0,4) == "Edge") {
            TopoDS_Edge edge = TopoDS::Edge(TopShape.getSubShape(aSubName.c_str()));
            const TopTools_ListOfShape& los = mapEdgeFace.FindFromKey(edge);

            if(los.Extent() != 2)
            {
                SubNames.erase(SubNames.begin()+i);
                continue;
            }

            const TopoDS_Shape& face1 = los.First();
            const TopoDS_Shape& face2 = los.Last();
            GeomAbs_Shape cont = BRep_Tool::Continuity(TopoDS::Edge(edge),
                                                       TopoDS::Face(face1),
                                                       TopoDS::Face(face2));
            if (cont != GeomAbs_C0) {
                SubNames.erase(SubNames.begin()+i);
                continue;
            }

            i++;
        }
        else if(aSubName.size() > 4 && aSubName.substr(0,4) == "Face") {
            TopoDS_Face face = TopoDS::Face(TopShape.getSubShape(aSubName.c_str()));

            TopTools_IndexedMapOfShape mapOfFaces;
            TopExp::MapShapes(face, TopAbs_EDGE, mapOfFaces);

            for(int j = 1; j <= mapOfFaces.Extent(); ++j) {
                TopoDS_Edge edge = TopoDS::Edge(mapOfFaces.FindKey(j));

                int id = mapOfEdges.FindIndex(edge);

                std::stringstream buf;
                buf << "Edge";
                buf << id;

                if(std::find(SubNames.begin(),SubNames.end(),buf.str()) == SubNames.end())
                {
                    SubNames.push_back(buf.str());
                }

            }

            SubNames.erase(SubNames.begin()+i);
        }
        // empty name or any other sub-element
        else {
            SubNames.erase(SubNames.begin()+i);
        }
    }

    if (SubNames.size() == 0) {
        QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
        QObject::tr("No chamfer possible on selected faces/edges"));
        return;
    }

    std::string SelString;
    SelString += "(App.";
    SelString += "ActiveDocument";//getObject()->getDocument()->getName();
    SelString += ".";
    SelString += selection[0].getFeatName();
    SelString += ",[";
    for(std::vector<std::string>::const_iterator it = SubNames.begin();it!=SubNames.end();++it){
        SelString += "\"";
        SelString += *it;
        SelString += "\"";
        if(it != --SubNames.end())
            SelString += ",";
    }
    SelString += "])";

    std::string FeatName = getUniqueObjectName("Chamfer");

    openCommand("Make Chamfer");
    doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::Chamfer\",\"%s\")",FeatName.c_str());
    doCommand(Doc,"App.activeDocument().%s.Base = %s",FeatName.c_str(),SelString.c_str());
    doCommand(Gui,"Gui.activeDocument().hide(\"%s\")",selection[0].getFeatName());
    doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str());

    copyVisual(FeatName.c_str(), "ShapeColor", selection[0].getFeatName());
    copyVisual(FeatName.c_str(), "LineColor",  selection[0].getFeatName());
    copyVisual(FeatName.c_str(), "PointColor", selection[0].getFeatName());
}