示例#1
0
bool Geometry::GetVertices(const TopoDS_Shape &brep, Geometry::VertexSet &vertices) {
    TopExp_Explorer anExp(brep, TopAbs_WIRE);
    int count=0;
    for (; anExp.More(); anExp.Next()){
        const TopoDS_Wire& w = TopoDS::Wire(anExp.Current());
        BRepTools_WireExplorer Ex;
        for (Ex.Init(w); Ex.More(); Ex.Next()) {
            //FIXME ifcopenshell already re-order the vertices, so no need to check the orientation, just use the natrual sequence, it works in most of the cases, but some exception still exists, e.g., part of the wall in the turkey building
            vertices.push_back(new TopoDS_Vertex);
            vertices.at(vertices.size()-1)=TopoDS::Vertex(Ex.CurrentVertex());
            count++;
        }
    }
//    if(count>=1)
//        cout<<"element: has "<<boost::lexical_cast<string>(count)<<" vertices"<<endl;
    if(count < 1)
        cout<<"error! no vertex is found in this building element"<<endl;
    return count>0;
}
示例#2
0
int OCCVertex::project(OCCBase *target) {
    Standard_Real First,Last,Best = 1e200;
    try {
        gp_Pnt pnt = BRep_Tool::Pnt(vertex);
        if (target->shapeType() == TopAbs_EDGE) {
            Handle(Geom_Curve) Curve = BRep_Tool::Curve(TopoDS::Edge(target->getShape()), First, Last);
            GeomAPI_ProjectPointOnCurve proj;
            proj.Init(pnt, Curve, First, Last);
            gp_Pnt aPnt = proj.NearestPoint();
            BRepBuilderAPI_MakeVertex mkVertex(aPnt);
            this->setShape(mkVertex.Vertex());
        } else if (target->shapeType() == TopAbs_WIRE) {
            BRepTools_WireExplorer exWire;
            for (exWire.Init(TopoDS::Wire(target->getShape())); exWire.More(); exWire.Next()) {
                const TopoDS_Edge& edge = exWire.Current();
                const Handle(Geom_Curve)& Curve = BRep_Tool::Curve(edge, First, Last);
                GeomAPI_ProjectPointOnCurve proj;
                proj.Init(pnt, Curve);
                gp_Pnt aPnt = proj.NearestPoint();
                if (proj.LowerDistance() < Best) {
                    Best = proj.LowerDistance();
                    pnt = aPnt;
                }
            }
            BRepBuilderAPI_MakeVertex mkVertex(pnt);
            this->setShape(mkVertex.Vertex());
        } else {
            gp_Pnt org = BRep_Tool::Pnt(vertex);
            BRepExtrema_DistShapeShape proj(this->getShape(), target->getShape());
            proj.Perform();
            for (int i = 1; i <= proj.NbSolution(); i++) {
                gp_Pnt aPnt = proj.PointOnShape2(i);
                if (org.Distance(aPnt) < Best) {
                    Best = org.Distance(aPnt);
                    pnt = aPnt;
                }
            }
            BRepBuilderAPI_MakeVertex mkVertex(pnt);
            this->setShape(mkVertex.Vertex());
        }
    } catch(Standard_Failure &err) {
示例#3
0
OCCTesselation *OCCWire::tesselate(double angular, double curvature)
{
    OCCTesselation *ret = new OCCTesselation();
    try {
        Standard_Real start, end;
        OCCStruct3f dtmp;
        
        // explore wire edges in connected order
        int lastSize = 0;
        BRepTools_WireExplorer exWire;
        
        for (exWire.Init(this->getWire()); exWire.More(); exWire.Next()) {
            const TopoDS_Edge& edge = exWire.Current();
            TopLoc_Location loc = edge.Location();
            gp_Trsf location = loc.Transformation();
            
            const Handle(Geom_Curve)& curve = BRep_Tool::Curve(edge, start, end);
            const GeomAdaptor_Curve& aCurve(curve);
            
            GCPnts_TangentialDeflection TD(aCurve, start, end, angular, curvature);
            
            ret->ranges.push_back(ret->vertices.size());
            
            for (Standard_Integer i = 1; i <= TD.NbPoints(); i++)
            {
                gp_Pnt pnt = TD.Value(i).Transformed(location);
                dtmp.x = (float)pnt.X();
                dtmp.y = (float)pnt.Y();
                dtmp.z = (float)pnt.Z();
                ret->vertices.push_back(dtmp);
            }
            
            ret->ranges.push_back(ret->vertices.size() - lastSize);
            lastSize = ret->vertices.size();
        }
    } catch(Standard_Failure &err) {
        return NULL;
    }
    return ret;
}
示例#4
0
Standard_Real ProjectPointOnWire(const TopoDS_Wire& wire, gp_Pnt p)
{
    double smallestDist = DBL_MAX;
    double alpha  = 0.;
    int edgeIndex = 0;

    // find edge with closest dist to point p
    BRepTools_WireExplorer wireExplorer;
    int iwire = 0;
    for (wireExplorer.Init(wire); wireExplorer.More(); wireExplorer.Next(), iwire++) {
        Standard_Real firstParam, lastParam;
        TopoDS_Edge edge = wireExplorer.Current();
        Handle(Geom_Curve) curve = BRep_Tool::Curve(edge, firstParam, lastParam);

        GeomAPI_ProjectPointOnCurve proj(p, curve, firstParam, lastParam);
        if (proj.NbPoints() > 0 && proj.LowerDistance() < smallestDist) {
            smallestDist = proj.LowerDistance();
            edgeIndex = iwire;
            alpha = proj.LowerDistanceParameter();
        }
    }

    // compute partial length of wire until projection point is reached
    wireExplorer.Init(wire);
    double partLength = 0.;
    for (int iwire = 0; iwire <= edgeIndex; ++iwire) {
        Standard_Real firstParam;
        Standard_Real lastParam;
        TopoDS_Edge edge = wireExplorer.Current();
        Handle(Geom_Curve) curve = BRep_Tool::Curve(edge, firstParam, lastParam);
        GeomAdaptor_Curve adaptorCurve(curve, firstParam, lastParam);
        if (iwire == edgeIndex) {
            lastParam = alpha;
        }

        partLength += GCPnts_AbscissaPoint::Length(adaptorCurve, firstParam, lastParam);
        wireExplorer.Next();
    }

    // return relative coordinate
    double normalizedLength = partLength/GetWireLength(wire);
    if (normalizedLength > 1.0) {
        normalizedLength = 1.0;
    }
    else if (normalizedLength < 0.0) {
        normalizedLength = 0.0;
    }
    return normalizedLength;
}
示例#5
0
//----------------------------------------------------------------
// Function: TopoDS_Shape level function to update the core Surface
//           for any movement  or Boolean operation of the body.
// Author: Jane Hu
//----------------------------------------------------------------
CubitStatus OCCSurface::update_OCC_entity(TopoDS_Face& old_surface,
                                          TopoDS_Shape& new_surface,
                                          BRepBuilderAPI_MakeShape *op,
                                          TopoDS_Vertex* removed_vertex,
                                          LocOpe_SplitShape* sp) 
{
  //set the Wires
  TopTools_IndexedMapOfShape M, M2;
  TopoDS_Shape shape, shape2, shape_edge, shape_vertex;
  TopExp::MapShapes(old_surface, TopAbs_WIRE, M);

  TopTools_ListOfShape shapes;  
  BRepFilletAPI_MakeFillet2d* test_op = NULL;

  for (int ii=1; ii<=M.Extent(); ii++) 
  {
     TopoDS_Wire wire = TopoDS::Wire(M(ii));
     TopTools_ListOfShape shapes;
     if(op)
     {
       test_op = dynamic_cast<BRepFilletAPI_MakeFillet2d*>(op);
       if(!test_op)
         shapes.Assign(op->Modified(wire));
       if(shapes.Extent() == 0)
         shapes.Assign(op->Generated(wire));
       if(!new_surface.IsNull())
         TopExp::MapShapes(new_surface,TopAbs_WIRE, M2);
     }
     else if(sp)
       shapes.Assign(sp->DescendantShapes(wire));

     if (shapes.Extent() == 1)
     {
       shape = shapes.First();
       if(M2.Extent() == 1)
       {
         shape2 = TopoDS::Wire(M2(1));
         if(!shape.IsSame(shape2))
           shape = shape2;
       }
       else if(M2.Extent() > 1)
         shape.Nullify();
     }
     else if(shapes.Extent() > 1)
       shape.Nullify();
     else if(op->IsDeleted(wire) || shapes.Extent() == 0)
     {
       TopTools_IndexedMapOfShape M_new;
       TopExp::MapShapes(new_surface, TopAbs_WIRE, M_new);
       if (M_new.Extent()== 1)
         shape = M_new(1);
       else
         shape.Nullify();
     }
     else
     {
       shape = wire;
       continue;
     }

     //set curves
     BRepTools_WireExplorer Ex;
      
     for(Ex.Init(wire); Ex.More();Ex.Next())
     {
       TopoDS_Edge edge = Ex.Current();
       if(op && !test_op)
       {
         shapes.Assign(op->Modified(edge));
         if(shapes.Extent() == 0)
           shapes.Assign(op->Generated(edge));
       }
         
       else if(sp)
         shapes.Assign(sp->DescendantShapes(edge));

       if (shapes.Extent() == 1)
       {
        //in fillet creating mothod, one edge could generated a face, so check
        //it here.
         TopAbs_ShapeEnum type = shapes.First().TShape()->ShapeType(); 
         if(type != TopAbs_EDGE)
           shape_edge.Nullify();
         else
           shape_edge = shapes.First();
       }
       else if (shapes.Extent() > 1)
       {
         //update all attributes first.
         TopTools_ListIteratorOfListOfShape it;
         it.Initialize(shapes);
         for(; it.More(); it.Next())
         {
           shape_edge = it.Value();
           OCCQueryEngine::instance()->copy_attributes(edge, shape_edge);
         }
         shape_edge.Nullify();
       }
       else if (op->IsDeleted(edge))
         shape_edge.Nullify(); 
       else if (test_op)
       {
         if(!test_op->IsModified(edge))
           shape_edge = edge;
         else
           shape_edge = (test_op->Modified(edge)).First();
       } 
       else
         shape_edge = edge;

       //update vertex
       TopoDS_Vertex vertex = Ex.CurrentVertex();
       shapes.Clear();
       if(test_op)
         assert(removed_vertex != NULL);

       if(op && ! test_op )
         shapes.Assign(op->Modified(vertex));
       else if(sp)
         shapes.Assign(sp->DescendantShapes(vertex));

       if (shapes.Extent() == 1)
         shape_vertex = shapes.First();

       else if(shapes.Extent() > 1)
       {
         //update all attributes first.
         TopTools_ListIteratorOfListOfShape it;
         it.Initialize(shapes);
         for(; it.More(); it.Next())
         {
           shape_vertex = it.Value();
           OCCQueryEngine::instance()->copy_attributes(vertex, shape_vertex);
         }
         shape_vertex.Nullify() ;
       }
       else if(op->IsDeleted(vertex) || (test_op && vertex.IsSame( *removed_vertex)))
         shape_vertex.Nullify() ;
         
       else
         shape_vertex = vertex;
      
       if(!vertex.IsSame(shape_vertex) )
         OCCQueryEngine::instance()->update_OCC_map(vertex, shape_vertex);

       if (!edge.IsSame(shape_edge))
         OCCQueryEngine::instance()->update_OCC_map(edge, shape_edge);
     }
     if (!wire.IsSame(shape))
       OCCQueryEngine::instance()->update_OCC_map(wire, shape);
  }
  double dTOL = OCCQueryEngine::instance()->get_sme_resabs_tolerance();
  if (!old_surface.IsSame(new_surface))
  {
    TopAbs_ShapeEnum shapetype =  TopAbs_SHAPE;
    if(!new_surface.IsNull())
      shapetype = new_surface.TShape()->ShapeType();  
    if(shapetype == TopAbs_FACE || new_surface.IsNull())
      OCCQueryEngine::instance()->update_OCC_map(old_surface, new_surface);
    else 
    {
      TopTools_IndexedMapOfShape M;
      TopExp::MapShapes(new_surface, TopAbs_FACE, M);   
      TopoDS_Shape new_shape;
      if(M.Extent() == 1)
        new_shape = M(1);
      else if(M.Extent() > 1)
      {
        for(int i = 1; i <= M.Extent(); i++)
        {
          GProp_GProps myProps;
          BRepGProp::SurfaceProperties(old_surface, myProps);
          double orig_mass = myProps.Mass();
          gp_Pnt orig_pnt = myProps.CentreOfMass();
          BRepGProp::SurfaceProperties(M(i), myProps);
          double after_mass = myProps.Mass();
          gp_Pnt after_pnt = myProps.CentreOfMass();
          if(fabs(-after_mass + orig_mass) <= dTOL && 
             orig_pnt.IsEqual(after_pnt, dTOL))
          {
            new_shape = M(i);
            break;
          }
        }
      }
      OCCQueryEngine::instance()->update_OCC_map(old_surface, new_shape);
    }
  }
  return CUBIT_SUCCESS;
}
示例#6
0
int OCCWire::fillet(std::vector<OCCVertex *> vertices, std::vector<double> radius) {
    int vertices_size = vertices.size();
    int radius_size = radius.size();
    
    BRepFilletAPI_MakeFillet2d MF;
    try {
        if (this->getShape().IsNull()) {
            StdFail_NotDone::Raise("Shapes is Null");
        }
        
        MF.Init(BRepBuilderAPI_MakeFace(this->getWire()));
        
        for (unsigned i=0; i<vertices.size(); i++) {
            OCCVertex *vertex = vertices[i];
            
            if (radius_size == 1) {
                // single radius
                MF.AddFillet(vertex->getVertex(), radius[0]);
            } else if (radius_size == vertices_size) {
                // radius given for each vertex
                MF.AddFillet(vertex->getVertex(), radius[i]);
            } else {
                StdFail_NotDone::Raise("radius argument has wrong size");
            }
        }
        
        if(MF.Status() != ChFi2d_IsDone)
            StdFail_NotDone::Raise("fillet not completed");
        
        BRepBuilderAPI_MakeWire wire;
        TopTools_IndexedMapOfShape aMap;
        BRepTools_WireExplorer Ex;
        
        TopExp::MapShapes(MF.Shape(), TopAbs_WIRE, aMap);
        if(aMap.Extent() != 1)
            StdFail_NotDone::Raise("Fillet operation did not result in single wire");
        
        //add edges to the wire
        Ex.Clear();
        for(Ex.Init(TopoDS::Wire(aMap(1))); Ex.More(); Ex.Next())
        {
            wire.Add(Ex.Current());
        }
          
        this->setShape(wire);
        
        // 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 fillet wire");
        }
        return 0;
    }
    return 1;
}