예제 #1
0
void FaceAdjacencySplitter::recursiveFind(const TopoDS_Face &face, FaceVectorType &outVector)
{
    outVector.push_back(face);

    const TopTools_ListOfShape &edges = faceToEdgeMap.FindFromKey(face);
    TopTools_ListIteratorOfListOfShape edgeIt;
    for (edgeIt.Initialize(edges); edgeIt.More(); edgeIt.Next())
    {
        //don't try to join across seams.
        // Note: BRep_Tool::IsClosed(TopoDS::Edge(edgeIt.Value()), face) is also possible?
        ShapeAnalysis_Edge edgeCheck;
        if(edgeCheck.IsSeam(TopoDS::Edge(edgeIt.Value()), face))
            continue;

        const TopTools_ListOfShape &faces = edgeToFaceMap.FindFromKey(edgeIt.Value());
        TopTools_ListIteratorOfListOfShape faceIt;
        for (faceIt.Initialize(faces); faceIt.More(); faceIt.Next())
        {
            if (!facesInMap.Contains(faceIt.Value()))
                continue;
            if (processedMap.Contains(faceIt.Value()))
                continue;
            processedMap.Add(faceIt.Value());
            recursiveFind(TopoDS::Face(faceIt.Value()), outVector);
        }
    }
}
예제 #2
0
ShapeHistory Feature::buildHistory(BRepBuilderAPI_MakeShape& mkShape, TopAbs_ShapeEnum type,
                                   const TopoDS_Shape& newS, const TopoDS_Shape& oldS)
{
    ShapeHistory history;
    history.type = type;

    TopTools_IndexedMapOfShape newM, oldM;
    TopExp::MapShapes(newS, type, newM); // map containing all old objects of type "type"
    TopExp::MapShapes(oldS, type, oldM); // map containing all new objects of type "type"

    // Look at all objects in the old shape and try to find the modified object in the new shape
    for (int i=1; i<=oldM.Extent(); i++) {
        bool found = false;
        TopTools_ListIteratorOfListOfShape it;
        // Find all new objects that are a modification of the old object (e.g. a face was resized)
        for (it.Initialize(mkShape.Modified(oldM(i))); it.More(); it.Next()) {
            found = true;
            for (int j=1; j<=newM.Extent(); j++) { // one old object might create several new ones!
                if (newM(j).IsPartner(it.Value())) {
                    history.shapeMap[i-1].push_back(j-1); // adjust indices to start at zero
                    break;
                }
            }
        }

        // Find all new objects that were generated from an old object (e.g. a face generated from an edge)
        for (it.Initialize(mkShape.Generated(oldM(i))); it.More(); it.Next()) {
            found = true;
            for (int j=1; j<=newM.Extent(); j++) {
                if (newM(j).IsPartner(it.Value())) {
                    history.shapeMap[i-1].push_back(j-1);
                    break;
                }
            }
        }

        if (!found) {
            // Find all old objects that don't exist any more (e.g. a face was completely cut away)
            if (mkShape.IsDeleted(oldM(i))) {
                history.shapeMap[i-1] = std::vector<int>();
            }
            else {
                // Mop up the rest (will this ever be reached?)
                for (int j=1; j<=newM.Extent(); j++) {
                    if (newM(j).IsPartner(oldM(i))) {
                        history.shapeMap[i-1].push_back(j-1);
                        break;
                    }
                }
            }
        }
    }

    return history;
}
예제 #3
0
//=======================================================================
//function : FillVertices
//purpose  :
//=======================================================================
void GEOMAlgo_Gluer2::FillVertices()
{
  TopAbs_ShapeEnum aType;
  TopoDS_Vertex aVnew;
  TopTools_ListIteratorOfListOfShape aItLS;
  TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItDMSLS;
  //
  myErrorStatus=0;
  myWarningStatus=0;
  //
  aItDMSLS.Initialize(myImagesToWork);
  for (; aItDMSLS.More(); aItDMSLS.Next()) {
    const TopoDS_Shape& aSkey=aItDMSLS.Key();
    aType=aSkey.ShapeType();
    if (aType!=TopAbs_VERTEX) {
      continue;
    }
    //
    const TopTools_ListOfShape& aLSD=aItDMSLS.Value();
    //
    GEOMAlgo_Gluer2::MakeVertex(aLSD, aVnew);
    //
    myImages.Bind(aVnew, aLSD);
    //
    aItLS.Initialize(aLSD);
    for (; aItLS.More(); aItLS.Next()) {
      const TopoDS_Shape& aV=aItLS.Value();
      myOrigins.Bind(aV, aVnew);
    }
  }
}
//=======================================================================
// function: IsExistingPaveBlock
// purpose:
//=======================================================================
Standard_Boolean NMTTools_PaveFiller::IsExistingPaveBlock(const BOPTools_PaveBlock& aPBNew,
                                                          const TopTools_ListOfShape& aLSE,
                                                          const Standard_Real aTolR3D)
{
  Standard_Boolean bFlag;
  Standard_Integer aNbSE, iC;
  Standard_Real aTolE, aTol;
  TopTools_ListIteratorOfListOfShape anIt;
  //
  bFlag=Standard_False;
  //
  aNbSE=aLSE.Extent();
  if (!aNbSE) {
    return bFlag;
  }
  //
  anIt.Initialize(aLSE);
  for (; anIt.More(); anIt.Next()) {
    const TopoDS_Edge& aE=TopoDS::Edge(anIt.Value());
    aTolE=BRep_Tool::Tolerance(aE);
    aTol=aTolR3D;
    if (aTolE>aTol) {
      aTol=aTolE;
    }
    iC=CheckIntermediatePoint(aPBNew, aE, aTol);
    if (!iC) {
      return !bFlag;
    }
  }
  return bFlag;
}
예제 #5
0
//----------------------------------------------------------------
// Function: to update the core Surface
//           for any movement  or Boolean operation of the body.
// Author: Jane Hu
//----------------------------------------------------------------
CubitStatus OCCSurface::update_OCC_entity( BRepBuilderAPI_Transform *aBRepTrsf,
                                         BRepAlgoAPI_BooleanOperation *op)
{
  assert(aBRepTrsf != NULL || op != NULL);

  TopoDS_Shape shape;
  if (aBRepTrsf)
    shape = aBRepTrsf->ModifiedShape(*get_TopoDS_Face());
  else
  {
    TopTools_ListOfShape shapes;
    shapes.Assign(op->Modified(*get_TopoDS_Face()));
    if(shapes.Extent() == 0)
         shapes.Assign(op->Generated(*get_TopoDS_Face()));
    if (shapes.Extent() == 1)
      shape = shapes.First();
    else if(shapes.Extent() > 1)
    {
      //update all attributes first.
      TopTools_ListIteratorOfListOfShape it;
      it.Initialize(shapes);
      for(; it.More(); it.Next())
      {
        shape = it.Value();
        OCCQueryEngine::instance()->copy_attributes(*get_TopoDS_Face(), shape);
      }
      shape = shapes.First();
    }
    else if(op->IsDeleted(*get_TopoDS_Face()))
      ;
    else
      return CUBIT_SUCCESS;
  }
 
  TopoDS_Face surface; 
  if(!shape.IsNull())
    surface = TopoDS::Face(shape);

  if (aBRepTrsf) 
  {
    //set the loops
    DLIList<OCCLoop *> loops;
    this->get_loops(loops);
    for (int i = 1; i <= loops.size(); i++)
    {
       OCCLoop *loop = loops.get_and_step();
       loop->update_OCC_entity(aBRepTrsf, op);
    }
    OCCQueryEngine::instance()->update_OCC_map(*myTopoDSFace, surface);
  }

  else if(op)
    update_OCC_entity(*myTopoDSFace, surface, op);

  return CUBIT_SUCCESS;
}
예제 #6
0
//=======================================================================
//function : FillBRepShapes
//purpose  :
//=======================================================================
void GEOMAlgo_Gluer2::FillBRepShapes(const TopAbs_ShapeEnum theType)
{
  Standard_Boolean bHasImage, bIsToWork;
  Standard_Integer i, aNbE;
  TopoDS_Iterator aItS;
  TopoDS_Shape aEnew;
  TopTools_IndexedMapOfShape aME;
  TopTools_MapOfShape aMFence;
  TopTools_ListIteratorOfListOfShape aItLS;
  //
  myErrorStatus=0;
  myWarningStatus=0;
  //
  TopExp::MapShapes(myArgument, theType, aME);
  //
  aNbE=aME.Extent();
  for (i=1; i<=aNbE; ++i) {
    const TopoDS_Shape& aE=aME(i);
    //
    if (!aMFence.Add(aE)) {
      continue;
    }
    //
    bIsToWork=myOriginsToWork.IsBound(aE);
    bHasImage=HasImage(aE);
    if (!bHasImage && !bIsToWork) {
      continue;
    }
    //
    MakeBRepShapes(aE, aEnew);
    //
    //myImages / myOrigins
    if (bIsToWork) {
      const TopoDS_Shape& aSkey=myOriginsToWork.Find(aE);
      const TopTools_ListOfShape& aLSD=myImagesToWork.Find(aSkey);
      //
      myImages.Bind(aEnew, aLSD);
      //
      aItLS.Initialize(aLSD);
      for (; aItLS.More(); aItLS.Next()) {
        const TopoDS_Shape& aEx=aItLS.Value();
        myOrigins.Bind(aEx, aEnew);
        //
        aMFence.Add(aEx);
      }
    }
    else {
      TopTools_ListOfShape aLSD;
      //
      aLSD.Append(aE);
      myImages.Bind(aEnew, aLSD);
      myOrigins.Bind(aE, aEnew);
    }
  }//for (i=1; i<=aNbF; ++i) {
}
예제 #7
0
Standard_Boolean Part::BRepBuilderAPI_RefineModel::IsDeleted(const TopoDS_Shape& S)
{
    TopTools_ListIteratorOfListOfShape it;
    for (it.Initialize(myDeleted); it.More(); it.Next())
    {
        if (it.Value().IsSame(S))
            return Standard_True;
    }

    return Standard_False;
}
예제 #8
0
void FaceAdjacencySplitter::recursiveFind(const TopoDS_Face &face, FaceVectorType &outVector)
{
    outVector.push_back(face);

    const TopTools_ListOfShape &edges = faceToEdgeMap.FindFromKey(face);
    TopTools_ListIteratorOfListOfShape edgeIt;
    for (edgeIt.Initialize(edges); edgeIt.More(); edgeIt.Next())
    {
        const TopTools_ListOfShape &faces = edgeToFaceMap.FindFromKey(edgeIt.Value());
        TopTools_ListIteratorOfListOfShape faceIt;
        for (faceIt.Initialize(faces); faceIt.More(); faceIt.Next())
        {
            if (!facesInMap.Contains(faceIt.Value()))
                continue;
            if (processedMap.Contains(faceIt.Value()))
                continue;
            processedMap.Add(faceIt.Value());
            recursiveFind(TopoDS::Face(faceIt.Value()), outVector);
        }
    }
}
예제 #9
0
//=======================================================================
//function : FillImagesCompound
//purpose  :
//=======================================================================
void FillImagesCompound(const TopoDS_Shape& theS,
                        BRepAlgo_Image& theImages,
                        TopTools_MapOfShape& theMFP)
{
    Standard_Boolean bInterferred;
    TopAbs_ShapeEnum aTypeX;
    TopAbs_Orientation aOrX;
    TopoDS_Iterator aIt;
    BRep_Builder aBB;
    TopTools_ListIteratorOfListOfShape aItIm;
    //
    if (!theMFP.Add(theS)) {
        return;
    }
    //
    bInterferred=Standard_False;
    aIt.Initialize(theS);
    for (; aIt.More(); aIt.Next()) {
        const TopoDS_Shape& aSX=aIt.Value();
        aTypeX=aSX.ShapeType();
        if (aTypeX==TopAbs_COMPOUND) {
            FillImagesCompound(aSX, theImages, theMFP);
        }
        if (theImages.HasImage(aSX)) {
            bInterferred=Standard_True;
        }
    }
    if (!bInterferred) {
        return;
    }
    //
    TopoDS_Shape aCIm;
    GEOMAlgo_Tools3D::MakeContainer(TopAbs_COMPOUND, aCIm);
    //
    aIt.Initialize(theS);
    for (; aIt.More(); aIt.Next()) {
        const TopoDS_Shape& aSX=aIt.Value();
        aOrX=aSX.Orientation();
        if (theImages.HasImage(aSX)) {
            const TopTools_ListOfShape& aLFIm=theImages.Image(aSX);
            aItIm.Initialize(aLFIm);
            for (; aItIm.More(); aItIm.Next()) {
                TopoDS_Shape aSXIm=aItIm.Value();
                aSXIm.Orientation(aOrX);
                aBB.Add(aCIm, aSXIm);
            }
        }
        else {
            aBB.Add(aCIm, aSX);
        }
    }
    theImages.Bind(theS, aCIm);
}
예제 #10
0
//=======================================================================
// function: FillImagesFaces1
// purpose:
//=======================================================================
void GEOMAlgo_Builder::FillImagesFaces1()
{
  Standard_Integer i, aNb, iSense, aNbLFx;
  TopoDS_Face aF, aFSp, aFSD;
  TopTools_ListOfShape aLFx;
  TopTools_ListIteratorOfListOfShape aIt;
  //
  const NMTDS_ShapesDataStructure& aDS=*myPaveFiller->DS();
  //
  aNb=aDS.NumberOfShapesOfTheObject();
  for (i=1; i<=aNb; ++i) {
    const TopoDS_Shape& aS=aDS.Shape(i);
    if (aS.ShapeType()!=TopAbs_FACE) {
      continue;
    }
    //
    if (!mySplitFaces.HasImage(aS)) {
      continue;
    }
    //
    aF=*((TopoDS_Face*)&aS);
    //
    aLFx.Clear();
    const TopTools_ListOfShape& aLF=mySplitFaces.Image(aF);
    aIt.Initialize(aLF);
    for (; aIt.More(); aIt.Next()) {
      aFSp=*((TopoDS_Face*)(&aIt.Value()));
      if (!mySameDomainShapes.Contains(aFSp)) {
        aLFx.Append(aFSp);
      }
      else {
        const TopoDS_Shape& aSx=mySameDomainShapes.FindFromKey(aFSp);
        aFSD=*((TopoDS_Face*)(&aSx));
        iSense=GEOMAlgo_Tools3D::Sense(aFSp, aFSD);
        if (iSense<0) {
          aFSD.Reverse();
        }
        aLFx.Append(aFSD);
      }
    }
    //
    if (!myImages.HasImage(aF)) {
      aNbLFx=aLFx.Extent();
      if (aNbLFx==1) {
        const TopoDS_Shape& aFx=aLFx.First();
        if (aF.IsSame(aFx)) {
          continue;
        }
      }
      myImages.Bind(aF, aLFx);
    }
  }
}
예제 #11
0
//=======================================================================
//function : Add
//purpose  : 
//=======================================================================
  void GEOMAlgo_ShapeSet::Add(const TopTools_ListOfShape& theLS)
{
  TopTools_ListIteratorOfListOfShape aIt;
  //
  aIt.Initialize(theLS);
  for (; aIt.More(); aIt.Next()) {
    const TopoDS_Shape& aS=aIt.Value();
    if (myMap.Add(aS)) {
      myList.Append(aS);
    }
  }
}
예제 #12
0
//=======================================================================
//function : Generated
//purpose  :
//=======================================================================
const TopTools_ListOfShape& GEOMAlgo_Builder::Generated(const TopoDS_Shape& theS)
{
    NMTTools_PaveFiller* pPF=myPaveFiller;
    const Handle(IntTools_Context)& aCtx=pPF->Context();
    //
    Standard_Boolean bHasImage, bToReverse;
    TopAbs_ShapeEnum aType;
    TopTools_ListIteratorOfListOfShape aIt;
    //
    myHistShapes.Clear();
    //
    if (theS.IsNull()) {
        return myHistShapes;
    }
    //
    bHasImage=myImages.HasImage(theS);
    if (!bHasImage) {
        return myHistShapes;
    }
    //
    aType=theS.ShapeType();
    //
    if (aType==TopAbs_EDGE   || aType==TopAbs_FACE ||
            aType==TopAbs_VERTEX || aType==TopAbs_SOLID) {
        const TopTools_ListOfShape& aLSp=myImages.Image(theS);
        aIt.Initialize(aLSp);
        for (; aIt.More(); aIt.Next()) {
            const TopoDS_Shape& aSp=aIt.Value();
            if (mySameDomainShapes.Contains(aSp)) {
                if (myMapShape.Contains(aSp)) {
                    TopoDS_Shape aSpR=mySameDomainShapes.FindFromKey(aSp);
                    //
                    if (aType==TopAbs_VERTEX || aType==TopAbs_SOLID) {
                        aSpR.Orientation(theS.Orientation());
                    }
                    else {
                        bToReverse=GEOMAlgo_Tools3D::IsSplitToReverse(aSpR, theS, aCtx);
                        if (bToReverse) {
                            aSpR.Reverse();
                        }
                    }
                    //
                    myHistShapes.Append(aSpR);
                }
            }
        }
    }
    //
    return myHistShapes;
}
예제 #13
0
//=======================================================================
//function : MakeInternalWires
//purpose  : 
//=======================================================================
void MakeInternalWires(const TopTools_MapOfShape& theME,
		       TopTools_ListOfShape& theWires)
{
  TopTools_MapIteratorOfMapOfShape aItM;
  TopTools_MapOfShape aAddedMap;
  TopTools_ListIteratorOfListOfShape aItE;
  TopTools_IndexedDataMapOfShapeListOfShape aMVE;
  BRep_Builder aBB;
  //
  aItM.Initialize(theME);
  for (; aItM.More(); aItM.Next()) {
    const TopoDS_Shape& aE=aItM.Key();
    TopExp::MapShapesAndAncestors(aE, TopAbs_VERTEX, TopAbs_EDGE, aMVE);
  }
  //
  aItM.Initialize(theME);
  for (; aItM.More(); aItM.Next()) {
    TopoDS_Shape aEE=aItM.Key();
    if (!aAddedMap.Add(aEE)) {
      continue;
    }
    //
    // make a new shell
    TopoDS_Wire aW;
    aBB.MakeWire(aW);    
    aEE.Orientation(TopAbs_INTERNAL);
    aBB.Add(aW, aEE);
    //
    TopoDS_Iterator aItAdded (aW);
    for (; aItAdded.More(); aItAdded.Next()) {
      const TopoDS_Shape& aE =aItAdded.Value();
      //
      TopExp_Explorer aExp(aE, TopAbs_VERTEX);
      for (; aExp.More(); aExp.Next()) {
        const TopoDS_Shape& aV =aExp.Current();
	const TopTools_ListOfShape& aLE=aMVE.FindFromKey(aV);
	aItE.Initialize(aLE);
	for (; aItE.More(); aItE.Next()) { 
	  TopoDS_Shape aEL=aItE.Value();
	  if (aAddedMap.Add(aEL)){
	    aEL.Orientation(TopAbs_INTERNAL);
	    aBB.Add(aW, aEL);
	  }
	}
      }
    }
    theWires.Append(aW);
  }
}
PyObject* BRepOffsetAPI_MakePipeShellPy::generated(PyObject *args)
{
    PyObject *shape;
    if (!PyArg_ParseTuple(args, "O!",&Part::TopoShapePy::Type,&shape))
        return 0;
    const TopoDS_Shape& s = static_cast<Part::TopoShapePy*>(shape)->getTopoShapePtr()->_Shape;
    const TopTools_ListOfShape& list = this->getBRepOffsetAPI_MakePipeShellPtr()->Generated(s);

    Py::List shapes;
    TopTools_ListIteratorOfListOfShape it;
    for (it.Initialize(list); it.More(); it.Next()) {
        const TopoDS_Shape& s = it.Value();
        shapes.append(Py::asObject(new TopoShapePy(new TopoShape(s))));
    }
    return Py::new_reference_to(shapes);
}
예제 #15
0
//=======================================================================
// function: SetEdges
// purpose: 
//=======================================================================
  void GEOMAlgo_WireSplitter::SetEdges(const TopTools_ListOfShape& aLE)
{
  TopTools_ListIteratorOfListOfShape anIt;
  //
  myEdges.Clear();
  anIt.Initialize(aLE);
  for (; anIt.More(); anIt.Next()) {
    const TopoDS_Shape& aE =anIt.Value();
    //
    if (aE.Orientation()==TopAbs_INTERNAL){
      continue;
    }
    //
    myEdges.Append(aE);
  }
}
예제 #16
0
//=======================================================================
//function : IsDeleted
//purpose  :
//=======================================================================
Standard_Boolean GEOMAlgo_Builder::IsDeleted(const TopoDS_Shape& theS)
{
    Standard_Boolean bRet, bHasImage, bContains;
    TopAbs_ShapeEnum aType;
    TopTools_ListIteratorOfListOfShape aIt;
    //
    bRet=Standard_False;
    //
    if (theS.IsNull()) {
        return !bRet; //true
    }
    //
    bContains=myMapShape.Contains(theS);
    if (bContains) {
        return bRet; //false
    }
    //
    bHasImage=myImages.HasImage(theS);
    if (!bHasImage) {
        return !bRet; //true
    }
    //
    aType=theS.ShapeType();
    if (aType==TopAbs_EDGE   || aType==TopAbs_FACE ||
            aType==TopAbs_VERTEX || aType==TopAbs_SOLID) {
        const TopTools_ListOfShape& aLSp=myImages.Image(theS);
        aIt.Initialize(aLSp);
        for (; aIt.More(); aIt.Next()) {
            TopoDS_Shape aSp=aIt.Value();
            //
            if (!mySameDomainShapes.Contains(aSp)) {
                if (myMapShape.Contains(aSp)) {
                    return bRet; //false
                }
            }
            else {
                TopoDS_Shape aSpR=mySameDomainShapes.FindFromKey(aSp);
                if (myMapShape.Contains(aSpR)) {
                    return bRet; //false
                }
            }
        }
    }
    return !bRet; // true
}
예제 #17
0
//=======================================================================
//function : FindDelta
//purpose  : 
//=======================================================================
static Standard_Real FindDelta(TopTools_ListOfShape& LE,
			       const TopoDS_Face& F)
{
  Standard_Real dist, f, l;
  Standard_Real d = Precision::Infinite();
  TopTools_ListIteratorOfListOfShape itl;

  for ( itl.Initialize(LE); itl.More(); itl.Next()) {
    const TopoDS_Edge& E = TopoDS::Edge(itl.Value());
    Handle(Geom2d_Curve) C = BRep_Tool::CurveOnSurface(E,F,f,l);
    gp_Pnt2d p = C->Value(f);
    gp_Pnt2d pp = C->Value(l);
    Standard_Real d1 = p.Distance(pp);
    if (d1<d) { d=d1;}
  }
  dist = d ;
  return dist;
}
예제 #18
0
//=======================================================================
//function : Subtract
//purpose  : 
//=======================================================================
  void GEOMAlgo_ShapeSet::Subtract(const GEOMAlgo_ShapeSet& theOther)
{
  TopTools_ListIteratorOfListOfShape aIt;
  TopTools_ListOfShape aLS;
  //
  myMap.Clear();
  aIt.Initialize(myList);
  for (; aIt.More(); aIt.Next()) {
    const TopoDS_Shape& aS=aIt.Value();
    if (!theOther.myMap.Contains(aS)) {
      if(myMap.Add(aS)){
	aLS.Append(aS);
      }
    }
  }
  //
  myList=aLS;
}
예제 #19
0
//=======================================================================
//function :SetShapes
//purpose  : 
//=======================================================================
  void NMTDS_PassKeyShape::SetShapes(const TopTools_ListOfShape& aLS)
{
  Standard_Integer i, aId, aIdN;
  TopTools_ListIteratorOfListOfShape aIt;
  //
  Clear();
  aIt.Initialize(aLS);
  for (; aIt.More(); aIt.Next()) {
    const TopoDS_Shape& aS=aIt.Value();
    myMap.Add(aS);
  }
  myNbIds=myMap.Extent();
  for(i=1; i<=myNbIds; ++i) {
    const TopoDS_Shape& aS=myMap(i);
    aId=aS.HashCode(myUpper);
    aIdN=NormalizedId(aId, myNbIds);
    mySum+=aIdN;
  }
}
예제 #20
0
//=======================================================================
//function : Contains
//purpose  : 
//=======================================================================
  Standard_Boolean GEOMAlgo_ShapeSet::Contains(const GEOMAlgo_ShapeSet& theOther)const
{
  Standard_Boolean bRet;
  TopAbs_Orientation aOr;
  TopTools_ListIteratorOfListOfShape aIt;
  //
  bRet=Standard_True;
  const TopTools_ListOfShape& aLS=theOther.GetSet();
  aIt.Initialize(aLS);
  for (; aIt.More(); aIt.Next()) {
    const TopoDS_Shape& aF=aIt.Value();
    aOr=aF.Orientation();
    if (aOr==TopAbs_FORWARD || aOr==TopAbs_REVERSED) {
      bRet=myMap.Contains(aF);
      if (!bRet) {
	break;
      }
    }
  }
  return bRet;
}
예제 #21
0
//=======================================================================
//function : CheckData
//purpose  :
//=======================================================================
void GEOMAlgo_Gluer2::CheckData()
{
  Standard_Integer aNbSG, i;
  TopAbs_ShapeEnum aType, aTypeX;
  TopTools_ListIteratorOfListOfShape aItLS;
  TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItDMSLS;
  //
  myErrorStatus=0;
  myWarningStatus=0;
  //
  aNbSG=myShapesToGlue.Extent();
  if (aNbSG) {
    // Check myShapesToGlue
    aItDMSLS.Initialize(myShapesToGlue);
    for (; aItDMSLS.More(); aItDMSLS.Next()) {
      //const TopoDS_Shape& aSkey=aItDMSLS.Key();
      const TopTools_ListOfShape& aLSG=aItDMSLS.Value();
      aItLS.Initialize(aLSG);
      for (i=0; aItLS.More(); aItLS.Next(), ++i) {
        const TopoDS_Shape& aSG=aItLS.Value();
        aTypeX=aSG.ShapeType();
        if (!i) {
          aType=aTypeX;
          if (!(aType==TopAbs_VERTEX ||
                aType==TopAbs_EDGE ||
                aType==TopAbs_FACE)) {
            myErrorStatus=21;// non-brep shapes
            return;
          }
          continue;
        }
        if (aTypeX!=aType) {
          myErrorStatus=20;// non-homogeneous shapes
          return;
        }
      }
    }
  }// if (aNbSG) {
}
예제 #22
0
//modified by NIZNHY-PKV Wed Oct 28 13:51:36 2010f
//=======================================================================
//function : IsEqual
//purpose  : 
//=======================================================================
  Standard_Boolean GEOMAlgo_ShapeSet::IsEqual(const GEOMAlgo_ShapeSet& theOther)const
{
  Standard_Boolean bRet;
  Standard_Integer aNb1, aNb2;
  TopTools_ListIteratorOfListOfShape aIt;
  //
  bRet=Standard_True;
  aNb1=myList.Extent();
  const TopTools_ListOfShape& aLS2=theOther.GetSet();
  aNb2=aLS2.Extent();
  if (aNb1!=aNb2) {
    return !bRet;
  }
  //
  aIt.Initialize(myList);
  for (; aIt.More(); aIt.Next()) {
    const TopoDS_Shape& aS=aIt.Value();
    if(!theOther.myMap.Contains(aS)) {
      bRet=!bRet;
      break;
    }
  }
  return bRet;
}
예제 #23
0
//=======================================================================
// function: FillImagesContainers
// purpose:
//=======================================================================
void GEOMAlgo_Builder::FillImagesContainers(const TopAbs_ShapeEnum theType)
{
    myErrorStatus=0;
    //
    Standard_Boolean bInterferred, bToReverse;
    Standard_Integer i, aNbS;
    TopAbs_ShapeEnum aType;
    BRep_Builder aBB;
    TopoDS_Iterator aIt;
    TopTools_ListIteratorOfListOfShape aItIm;
    TopTools_MapOfShape aMS;
    TopTools_MapIteratorOfMapOfShape aItS;
    //
    const NMTDS_ShapesDataStructure& aDS=*myPaveFiller->DS();
    NMTTools_PaveFiller* pPF=myPaveFiller;
    const Handle(IntTools_Context)& aCtx= pPF->Context();
    //
    aNbS=aDS.NumberOfShapesOfTheObject();
    for (i=1; i<=aNbS; ++i) {
        const TopoDS_Shape& aC=aDS.Shape(i);
        aType=aC.ShapeType();
        if (aType==theType) {
            aMS.Add(aC);
        }
    }
    //
    if (theType==TopAbs_COMPOUND) {
        FillImagesCompounds(aMS, myImages);
        return;
    }
    //
    aItS.Initialize(aMS);
    for (; aItS.More(); aItS.Next()) {
        const TopoDS_Shape& aC=aItS.Key();
        // whether the shape has image
        bInterferred=Standard_False;
        aIt.Initialize(aC);
        for (; aIt.More(); aIt.Next()) {
            const TopoDS_Shape& aF=aIt.Value();
            if (myImages.HasImage(aF)) {
                bInterferred=!bInterferred;
                break;
            }
        }
        if (!bInterferred) {
            continue;
        }
        //
        TopoDS_Shape aCIm;
        GEOMAlgo_Tools3D::MakeContainer(theType, aCIm);
        //
        aIt.Initialize(aC);
        for (; aIt.More(); aIt.Next()) {
            const TopoDS_Shape& aF=aIt.Value();
            if (myImages.HasImage(aF)) {
                const TopTools_ListOfShape& aLFIm=myImages.Image(aF);
                aItIm.Initialize(aLFIm);
                for (; aItIm.More(); aItIm.Next()) {
                    TopoDS_Shape aFIm=aItIm.Value();
                    //
                    bToReverse=GEOMAlgo_Tools3D::IsSplitToReverse(aFIm, aF, aCtx);
                    if (bToReverse) {
                        aFIm.Reverse();
                    }
                    aBB.Add(aCIm, aFIm);
                }
            }
            else {
                aBB.Add(aCIm, aF);
            }
        }
        myImages.Bind(aC, aCIm);
    }// for (; aItS.More(); aItS.Next()) {
}
//=======================================================================
//function : DetectShapes
//purpose  :
//=======================================================================
  void GEOMAlgo_GlueAnalyser::DetectShapes(const TopAbs_ShapeEnum aType)
{
  myErrorStatus=0;
  //
  Standard_Integer i, aNbF, aNbSDF, iErr;
  TopoDS_Shape aNewShape;
  TopTools_IndexedMapOfShape aMF;
  TopTools_ListIteratorOfListOfShape aItS;
  GEOMAlgo_PassKeyShape aPKF;
  GEOMAlgo_IndexedDataMapOfPassKeyShapeListOfShape aMPKLF;
  //
  TopExp::MapShapes(myShape, aType, aMF);
  //
  aNbF=aMF.Extent();
  for (i=1; i<=aNbF; ++i) {
    const TopoDS_Shape& aS=aMF(i);
    //
    //aPKF.Clear();//qft
    if (aType==TopAbs_FACE) {
      const TopoDS_Face& aF=TopoDS::Face(aS);
      FacePassKey(aF, aPKF);
    }
    else if (aType==TopAbs_EDGE) {
      const TopoDS_Edge& aE=TopoDS::Edge(aS);
      EdgePassKey(aE, aPKF);
    }
    //
    if (myErrorStatus) {
      return;
    }
    //
    if (aMPKLF.Contains(aPKF)) {
      TopTools_ListOfShape& aLSDF=aMPKLF.ChangeFromKey(aPKF);
      aLSDF.Append(aS);
    }
    else {
      TopTools_ListOfShape aLSDF;
      //
      aLSDF.Append(aS);
      aMPKLF.Add(aPKF, aLSDF);
    }
  }
  // check geometric coincidence
  if (myCheckGeometry) {
    iErr=GEOMAlgo_Tools::RefineSDShapes(aMPKLF, myTol, myContext); //XX
    if (iErr) {
      myErrorStatus=200;
      return;
    }
  }
  //
  // Images/Origins
  aNbF=aMPKLF.Extent();
  for (i=1; i<=aNbF; ++i) {
    const TopTools_ListOfShape& aLSDF=aMPKLF(i);
    aNbSDF=aLSDF.Extent();
    if (!aNbSDF) {
      myErrorStatus=4; // it must not be
    }
    //
    const TopoDS_Shape& aS1=aLSDF.First();
    aNewShape=aS1;
    //
    myImages.Bind(aNewShape, aLSDF);
    // origins
    aItS.Initialize(aLSDF);
    for (; aItS.More(); aItS.Next()) {
      const TopoDS_Shape& aFSD=aItS.Value();
      if (!myOrigins.IsBound(aFSD)) {
        myOrigins.Bind(aFSD, aNewShape);
      }
    }
  }
}
예제 #25
0
App::DocumentObjectExecReturn *Sweep::execute(void)
{
    if (Sections.getSize() == 0)
        return new App::DocumentObjectExecReturn("No sections linked.");
    App::DocumentObject* spine = Spine.getValue();
    if (!(spine && spine->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())))
        return new App::DocumentObjectExecReturn("No spine linked.");
    const std::vector<std::string>& subedge = Spine.getSubValues();

    TopoDS_Shape path;
    const Part::TopoShape& shape = static_cast<Part::Feature*>(spine)->Shape.getValue();
    if (!shape._Shape.IsNull()) {
        try {
            if (!subedge.empty()) {
                BRepBuilderAPI_MakeWire mkWire;
                for (std::vector<std::string>::const_iterator it = subedge.begin(); it != subedge.end(); ++it) {
                    TopoDS_Shape subshape = shape.getSubShape(it->c_str());
                    mkWire.Add(TopoDS::Edge(subshape));
                }
                path = mkWire.Wire();
            }
            else if (shape._Shape.ShapeType() == TopAbs_EDGE) {
                path = shape._Shape;
            }
            else if (shape._Shape.ShapeType() == TopAbs_WIRE) {
                BRepBuilderAPI_MakeWire mkWire(TopoDS::Wire(shape._Shape));
                path = mkWire.Wire();
            }
            else if (shape._Shape.ShapeType() == TopAbs_COMPOUND) {
                TopoDS_Iterator it(shape._Shape);
                for (; it.More(); it.Next()) {
                    if (it.Value().IsNull())
                        return new App::DocumentObjectExecReturn("In valid element in spine.");
                    if ((it.Value().ShapeType() != TopAbs_EDGE) &&
                        (it.Value().ShapeType() != TopAbs_WIRE)) {
                        return new App::DocumentObjectExecReturn("Element in spine is neither an edge nor a wire.");
                    }
                }

                Handle(TopTools_HSequenceOfShape) hEdges = new TopTools_HSequenceOfShape();
                Handle(TopTools_HSequenceOfShape) hWires = new TopTools_HSequenceOfShape();
                for (TopExp_Explorer xp(shape._Shape, TopAbs_EDGE); xp.More(); xp.Next())
                    hEdges->Append(xp.Current());

                ShapeAnalysis_FreeBounds::ConnectEdgesToWires(hEdges, Precision::Confusion(), Standard_True, hWires);
                int len = hWires->Length();
                if (len != 1)
                    return new App::DocumentObjectExecReturn("Spine is not connected.");
                path = hWires->Value(1);
            }
            else {
                return new App::DocumentObjectExecReturn("Spine is neither an edge nor a wire.");
            }
        }
        catch (Standard_Failure) {
            return new App::DocumentObjectExecReturn("Invalid spine.");
        }
    }

    try {
        TopTools_ListOfShape profiles;
        const std::vector<App::DocumentObject*>& shapes = Sections.getValues();
        std::vector<App::DocumentObject*>::const_iterator it;
        for (it = shapes.begin(); it != shapes.end(); ++it) {
            if (!(*it)->isDerivedFrom(Part::Feature::getClassTypeId()))
                return new App::DocumentObjectExecReturn("Linked object is not a shape.");
            TopoDS_Shape shape = static_cast<Part::Feature*>(*it)->Shape.getValue();
            if (shape.IsNull())
                return new App::DocumentObjectExecReturn("Linked shape is invalid.");

            // Extract first element of a compound
            if (shape.ShapeType() == TopAbs_COMPOUND) {
                TopoDS_Iterator it(shape);
                for (; it.More(); it.Next()) {
                    if (!it.Value().IsNull()) {
                        shape = it.Value();
                        break;
                    }
                }
            }
            // There is a weird behaviour of BRepOffsetAPI_MakePipeShell when trying to add the wire as is.
            // If we re-create the wire then everything works fine.
            // http://forum.freecadweb.org/viewtopic.php?f=10&t=2673&sid=fbcd2ff4589f0b2f79ed899b0b990648#p20268
            if (shape.ShapeType() == TopAbs_FACE) {
                TopoDS_Wire faceouterWire = ShapeAnalysis::OuterWire(TopoDS::Face(shape));
                profiles.Append(faceouterWire);
            }
            else if (shape.ShapeType() == TopAbs_WIRE) {
                BRepBuilderAPI_MakeWire mkWire(TopoDS::Wire(shape));
                profiles.Append(mkWire.Wire());
            }
            else if (shape.ShapeType() == TopAbs_EDGE) {
                BRepBuilderAPI_MakeWire mkWire(TopoDS::Edge(shape));
                profiles.Append(mkWire.Wire());
            }
            else if (shape.ShapeType() == TopAbs_VERTEX) {
                profiles.Append(shape);
            }
            else {
                return new App::DocumentObjectExecReturn("Linked shape is not a vertex, edge, wire nor face.");
            }
        }

        Standard_Boolean isSolid = Solid.getValue() ? Standard_True : Standard_False;
        Standard_Boolean isFrenet = Frenet.getValue() ? Standard_True : Standard_False;
        BRepBuilderAPI_TransitionMode transMode;
        switch (Transition.getValue()) {
            case 1: transMode = BRepBuilderAPI_RightCorner;
                break;
            case 2: transMode = BRepBuilderAPI_RoundCorner;
                break;
            default: transMode = BRepBuilderAPI_Transformed;
                break;
        }

        if (path.ShapeType() == TopAbs_EDGE) {
            BRepBuilderAPI_MakeWire mkWire(TopoDS::Edge(path));
            path = mkWire.Wire();
        }

        BRepOffsetAPI_MakePipeShell mkPipeShell(TopoDS::Wire(path));
        mkPipeShell.SetMode(isFrenet);
        mkPipeShell.SetTransitionMode(transMode);
        TopTools_ListIteratorOfListOfShape iter;
        for (iter.Initialize(profiles); iter.More(); iter.Next()) {
            mkPipeShell.Add(TopoDS_Shape(iter.Value()));
        }

        if (!mkPipeShell.IsReady())
            Standard_Failure::Raise("shape is not ready to build");
        mkPipeShell.Build();
        if (isSolid)
            mkPipeShell.MakeSolid();

        this->Shape.setValue(mkPipeShell.Shape());
        return App::DocumentObject::StdReturn;
    }
    catch (Standard_Failure) {
        Handle_Standard_Failure e = Standard_Failure::Caught();
        return new App::DocumentObjectExecReturn(e->GetMessageString());
    }
    catch (...) {
        return new App::DocumentObjectExecReturn("A fatal error occurred when making the sweep");
    }
}
//=======================================================================
//function : DetectVertices
//purpose  :
//=======================================================================
  void GEOMAlgo_GlueAnalyser::DetectVertices()
{
  myErrorStatus=0;
  //
  Standard_Integer j, i, aNbV, aIndex, aNbVSD;
  TColStd_ListIteratorOfListOfInteger aIt;
  Handle(Bnd_HArray1OfBox) aHAB;
  Bnd_BoundSortBox aBSB;
  TopoDS_Shape aSTmp, aVF;
  TopoDS_Vertex aVnew;
  TopTools_IndexedMapOfShape aMV, aMVProcessed;
  TopTools_ListIteratorOfListOfShape aItS;
  TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItIm;
  GEOMAlgo_IndexedDataMapOfIntegerShape aMIS;
  GEOMAlgo_IndexedDataMapOfShapeBox aMSB;
  //
  TopExp::MapShapes(myShape, TopAbs_VERTEX, aMV);
  aNbV=aMV.Extent();
  if (!aNbV) {
    myErrorStatus=2; // no vertices in source shape
    return;
  }
  //
  aHAB=new Bnd_HArray1OfBox(1, aNbV);
  //
  for (i=1; i<=aNbV; ++i) {
    const TopoDS_Shape& aV=aMV(i);
    Bnd_Box aBox;
    //
    aBox.SetGap(myTol);
    BRepBndLib::Add(aV, aBox);
    aHAB->SetValue(i, aBox);
    aMIS.Add(i, aV);
    aMSB.Add(aV, aBox);
  }
  //
  aBSB.Initialize(aHAB);
  //
  for (i=1; i<=aNbV; ++i) {
    const TopoDS_Shape& aV=aMV(i);
    //
    if (aMVProcessed.Contains(aV)) {
      continue;
    }
    //
    const Bnd_Box& aBoxV=aMSB.FindFromKey(aV);
    const TColStd_ListOfInteger& aLI=aBSB.Compare(aBoxV);
    aNbVSD=aLI.Extent();
    if (!aNbVSD) {
      myErrorStatus=3; // it must not be
      return;
    }
    //
    // Images
    TopTools_ListOfShape aLVSD;
    //
    aIt.Initialize(aLI);
    for (j=0; aIt.More(); aIt.Next(), ++j) {
      aIndex=aIt.Value();
      const TopoDS_Shape& aVx=aMIS.FindFromKey(aIndex);
      if(!j) {
        aVF=aVx;
      }
      aLVSD.Append(aVx);
      aMVProcessed.Add(aVx);
    }
    myImages.Bind(aVF, aLVSD);
  }
  // Origins
  aItIm.Initialize(myImages);
  for (; aItIm.More(); aItIm.Next()) {
    const TopoDS_Shape& aV=aItIm.Key();
    const TopTools_ListOfShape& aLVSD=aItIm.Value();
    //
    aItS.Initialize(aLVSD);
    for (; aItS.More(); aItS.Next()) {
      const TopoDS_Shape& aVSD=aItS.Value();
      if (!myOrigins.IsBound(aVSD)) {
        myOrigins.Bind(aVSD, aV);
      }
    }
  }
}
bool NETGENPlugin_Mesher::fillNgMesh(netgen::OCCGeometry&           occgeom,
                                     netgen::Mesh&                  ngMesh,
                                     vector<SMDS_MeshNode*>&        nodeVec,
                                     const list< SMESH_subMesh* > & meshedSM)
{
  TNode2IdMap nodeNgIdMap;

  TopTools_MapOfShape visitedShapes;

  SMESH_MesherHelper helper (*_mesh);

  int faceID = occgeom.fmap.Extent();
  _faceDescriptors.clear();

  list< SMESH_subMesh* >::const_iterator smIt, smEnd = meshedSM.end();
  for ( smIt = meshedSM.begin(); smIt != smEnd; ++smIt )
  {
    SMESH_subMesh* sm = *smIt;
    if ( !visitedShapes.Add( sm->GetSubShape() ))
      continue;

    SMESHDS_SubMesh * smDS = sm->GetSubMeshDS();

    switch ( sm->GetSubShape().ShapeType() )
    {
    case TopAbs_EDGE: { // EDGE
      // ----------------------
      const TopoDS_Edge& geomEdge  = TopoDS::Edge( sm->GetSubShape() );

      // Add ng segments for each not meshed face the edge bounds
      TopTools_MapOfShape visitedAncestors;
      const TopTools_ListOfShape& ancestors = _mesh->GetAncestors( geomEdge );
      TopTools_ListIteratorOfListOfShape ancestorIt ( ancestors );
      for ( ; ancestorIt.More(); ancestorIt.Next() )
      {
        const TopoDS_Shape & ans = ancestorIt.Value();
        if ( ans.ShapeType() != TopAbs_FACE || !visitedAncestors.Add( ans ))
          continue;
        const TopoDS_Face& face = TopoDS::Face( ans );

        int faceID = occgeom.fmap.FindIndex( face );
        if ( faceID < 1 )
          continue; // meshed face

        // find out orientation of geomEdge within face
        bool isForwad = false;
        for ( TopExp_Explorer exp( face, TopAbs_EDGE ); exp.More(); exp.Next() ) {
          if ( geomEdge.IsSame( exp.Current() )) {
            isForwad = ( exp.Current().Orientation() == geomEdge.Orientation() );
            break;
          }
        }
        bool isQuad = smDS->GetElements()->next()->IsQuadratic();

        // get all nodes from geomEdge
        StdMeshers_FaceSide fSide( face, geomEdge, _mesh, isForwad, isQuad );
        const vector<UVPtStruct>& points = fSide.GetUVPtStruct();
        int i, nbSeg = fSide.NbSegments();

        double otherSeamParam = 0;
        helper.SetSubShape( face );
        bool isSeam = helper.IsRealSeam( geomEdge );
        if ( isSeam )
          otherSeamParam =
            helper.GetOtherParam( helper.GetPeriodicIndex() == 1 ? points[0].u : points[0].v );

        // add segments

        int prevNgId = ngNodeId( points[0].node, ngMesh, nodeNgIdMap );

        for ( i = 0; i < nbSeg; ++i )
        {
          const UVPtStruct& p1 = points[ i ];
          const UVPtStruct& p2 = points[ i+1 ];

          netgen::Segment seg;
          // ng node ids
          seg.p1 = prevNgId;
          seg.p2 = prevNgId = ngNodeId( p2.node, ngMesh, nodeNgIdMap );
          // node param on curve
          seg.epgeominfo[ 0 ].dist = p1.param;
          seg.epgeominfo[ 1 ].dist = p2.param;
          // uv on face
          seg.epgeominfo[ 0 ].u = p1.u;
          seg.epgeominfo[ 0 ].v = p1.v;
          seg.epgeominfo[ 1 ].u = p2.u;
          seg.epgeominfo[ 1 ].v = p2.v;

          //seg.epgeominfo[ iEnd ].edgenr = edgeID; //  = geom.emap.FindIndex(edge);
          seg.si = faceID;                   // = geom.fmap.FindIndex (face);
          seg.edgenr = ngMesh.GetNSeg() + 1; // segment id
          ngMesh.AddSegment (seg);

          if ( isSeam )
          {
            if ( helper.GetPeriodicIndex() == 1 ) {
              seg.epgeominfo[ 0 ].u = otherSeamParam;
              seg.epgeominfo[ 1 ].u = otherSeamParam;
              swap (seg.epgeominfo[0].v, seg.epgeominfo[1].v);
            } else {
              seg.epgeominfo[ 0 ].v = otherSeamParam;
              seg.epgeominfo[ 1 ].v = otherSeamParam;
              swap (seg.epgeominfo[0].u, seg.epgeominfo[1].u);
            }
            swap (seg.p1, seg.p2);
            swap (seg.epgeominfo[0].dist, seg.epgeominfo[1].dist);
            seg.edgenr = ngMesh.GetNSeg() + 1; // segment id
            ngMesh.AddSegment (seg);
          }
        }
      } // loop on geomEdge ancestors

      break;
    } // case TopAbs_EDGE

    case TopAbs_FACE: { // FACE
      // ----------------------
      const TopoDS_Face& geomFace  = TopoDS::Face( sm->GetSubShape() );
      helper.SetSubShape( geomFace );

      // Find solids the geomFace bounds
      int solidID1 = 0, solidID2 = 0;
      const TopTools_ListOfShape& ancestors = _mesh->GetAncestors( geomFace );
      TopTools_ListIteratorOfListOfShape ancestorIt ( ancestors );
      for ( ; ancestorIt.More(); ancestorIt.Next() )
      {
        const TopoDS_Shape & solid = ancestorIt.Value();
        if ( solid.ShapeType() == TopAbs_SOLID  ) {
          int id = occgeom.somap.FindIndex ( solid );
          if ( solidID1 && id != solidID1 ) solidID2 = id;
          else                              solidID1 = id;
        }
      }
      faceID++;
      _faceDescriptors[ faceID ].first  = solidID1;
      _faceDescriptors[ faceID ].second = solidID2;

      // Orient the face correctly in solidID1 (issue 0020206)
      bool reverse = false;
      if ( solidID1 ) {
        TopoDS_Shape solid = occgeom.somap( solidID1 );
        for ( TopExp_Explorer f( solid, TopAbs_FACE ); f.More(); f.Next() ) {
          if ( geomFace.IsSame( f.Current() )) {
            reverse = SMESH_Algo::IsReversedSubMesh( TopoDS::Face( f.Current()), helper.GetMeshDS() );
            break;
          }
        }
      }

      // Add surface elements
      SMDS_ElemIteratorPtr faces = smDS->GetElements();
      while ( faces->more() ) {

        const SMDS_MeshElement* f = faces->next();
        if ( f->NbNodes() % 3 != 0 ) { // not triangle
          for ( ancestorIt.Initialize(ancestors); ancestorIt.More(); ancestorIt.Next() )
            if ( ancestorIt.Value().ShapeType() == TopAbs_SOLID  ) {
              sm = _mesh->GetSubMesh( ancestorIt.Value() );
              break;
            }
          SMESH_ComputeErrorPtr& smError = sm->GetComputeError();
          smError.reset( new SMESH_ComputeError(COMPERR_BAD_INPUT_MESH,"Not triangle submesh"));
          smError->myBadElements.push_back( f );
          return false;
        }

        netgen::Element2d tri(3);
        tri.SetIndex ( faceID );

        for ( int i = 0; i < 3; ++i ) {
          const SMDS_MeshNode* node = f->GetNode( i ), * inFaceNode=0;
          if ( helper.IsSeamShape( node->GetPosition()->GetShapeId() ))
            if ( helper.IsSeamShape( f->GetNodeWrap( i+1 )->GetPosition()->GetShapeId() ))
              inFaceNode = f->GetNodeWrap( i-1 );
            else 
              inFaceNode = f->GetNodeWrap( i+1 );

          gp_XY uv = helper.GetNodeUV( geomFace, node, inFaceNode );
          if ( reverse ) {
            tri.GeomInfoPi(3-i).u = uv.X();
            tri.GeomInfoPi(3-i).v = uv.Y();
            tri.PNum      (3-i) = ngNodeId( node, ngMesh, nodeNgIdMap );
          } else {
            tri.GeomInfoPi(i+1).u = uv.X();
            tri.GeomInfoPi(i+1).v = uv.Y();
            tri.PNum      (i+1) = ngNodeId( node, ngMesh, nodeNgIdMap );
          }
        }

        ngMesh.AddSurfaceElement (tri);

      }
      break;
    } //

    case TopAbs_VERTEX: { // VERTEX
      // --------------------------
      SMDS_NodeIteratorPtr nodeIt = smDS->GetNodes();
      if ( nodeIt->more() )
        ngNodeId( nodeIt->next(), ngMesh, nodeNgIdMap );
      break;
    }
    default:;
    } // switch
  } // loop on submeshes

  // fill nodeVec
  nodeVec.resize( ngMesh.GetNP() + 1 );
  TNode2IdMap::iterator node_NgId, nodeNgIdEnd = nodeNgIdMap.end();
  for ( node_NgId = nodeNgIdMap.begin(); node_NgId != nodeNgIdEnd; ++node_NgId)
    nodeVec[ node_NgId->second ] = (SMDS_MeshNode*) node_NgId->first;

  return true;
}
예제 #28
0
bool FaceUniter::process()
{
    if (workShell.IsNull())
        return false;
    modifiedShapes.clear();
    deletedShapes.clear();
    typeObjects.push_back(&getPlaneObject());
    typeObjects.push_back(&getCylinderObject());
    //add more face types.

    ModelRefine::FaceTypeSplitter splitter;
    splitter.addShell(workShell);
    std::vector<FaceTypedBase *>::iterator typeIt;
    for(typeIt = typeObjects.begin(); typeIt != typeObjects.end(); ++typeIt)
        splitter.registerType((*typeIt)->getType());
    splitter.split();

    ModelRefine::FaceVectorType facesToRemove;
    ModelRefine::FaceVectorType facesToSew;

    ModelRefine::FaceAdjacencySplitter adjacencySplitter(workShell);

    for(typeIt = typeObjects.begin(); typeIt != typeObjects.end(); ++typeIt)
    {
        ModelRefine::FaceVectorType typedFaces = splitter.getTypedFaceVector((*typeIt)->getType());
        ModelRefine::FaceEqualitySplitter equalitySplitter;
        equalitySplitter.split(typedFaces, *typeIt);
        for (std::size_t indexEquality(0); indexEquality < equalitySplitter.getGroupCount(); ++indexEquality)
        {
            adjacencySplitter.split(equalitySplitter.getGroup(indexEquality));
//            std::cout << "      adjacency group count: " << adjacencySplitter.getGroupCount() << std::endl;
            for (std::size_t adjacentIndex(0); adjacentIndex < adjacencySplitter.getGroupCount(); ++adjacentIndex)
            {
//                    std::cout << "         face count is: " << adjacencySplitter.getGroup(adjacentIndex).size() << std::endl;
                TopoDS_Face newFace = (*typeIt)->buildFace(adjacencySplitter.getGroup(adjacentIndex));
                if (!newFace.IsNull())
                {
                    facesToSew.push_back(newFace);
                    if (facesToRemove.capacity() <= facesToRemove.size() + adjacencySplitter.getGroup(adjacentIndex).size())
                        facesToRemove.reserve(facesToRemove.size() + adjacencySplitter.getGroup(adjacentIndex).size());
                    FaceVectorType temp = adjacencySplitter.getGroup(adjacentIndex);
                    facesToRemove.insert(facesToRemove.end(), temp.begin(), temp.end());
                    // the first shape will be marked as modified, i.e. replaced by newFace, all others are marked as deleted
                    // jrheinlaender: IMHO this is not correct because references to the deleted faces will be broken, whereas they should
                    // be replaced by references to the new face. To achieve this all shapes should be marked as
                    // modified, producing one single new face. This is the inverse behaviour to faces that are split e.g.
                    // by a boolean cut, where one old shape is marked as modified, producing multiple new shapes
                    if (!temp.empty())
                    {
                        for (FaceVectorType::iterator f = temp.begin(); f != temp.end(); ++f)
                              modifiedShapes.push_back(std::make_pair(*f, newFace));
                    }
                }
            }
        }
    }
    if (facesToSew.size() > 0)
    {
        modifiedSignal = true;
        workShell = ModelRefine::removeFaces(workShell, facesToRemove);
        TopExp_Explorer xp;
        bool emptyShell = true;
        for (xp.Init(workShell, TopAbs_FACE); xp.More(); xp.Next())
        {
            emptyShell = false;
            break;
        }

        if (!emptyShell || facesToSew.size() > 1)
        {
            BRepBuilderAPI_Sewing sew;
            sew.Add(workShell);
            FaceVectorType::iterator sewIt;
            for(sewIt = facesToSew.begin(); sewIt != facesToSew.end(); ++sewIt)
                sew.Add(*sewIt);
            sew.Perform();
            try {
                workShell = TopoDS::Shell(sew.SewedShape());
            } catch (Standard_Failure) {
                return false;
            }
            // update the list of modifications
            for (std::vector<ShapePairType>::iterator it = modifiedShapes.begin(); it != modifiedShapes.end(); ++it)
            {
                if (sew.IsModified(it->second))
                {
                    it->second = sew.Modified(it->second);
                    break;
                }
            }
        }
        else
        {
            // workShell has no more faces and we add exactly one face
            BRep_Builder builder;
            builder.MakeShell(workShell);
            FaceVectorType::iterator sewIt;
            for(sewIt = facesToSew.begin(); sewIt != facesToSew.end(); ++sewIt)
                builder.Add(workShell, *sewIt);
        }
        
        BRepLib_FuseEdges edgeFuse(workShell);
// TODO: change this version after occ fix. Freecad Mantis 1450
#if OCC_VERSION_HEX <= 0x070000
        TopTools_IndexedMapOfShape map;
        collectConicEdges(workShell, map);
        edgeFuse.AvoidEdges(map);
#endif
        TopTools_DataMapOfShapeShape affectedFaces;
        edgeFuse.Faces(affectedFaces);
        TopTools_DataMapIteratorOfDataMapOfShapeShape mapIt;
        for (mapIt.Initialize(affectedFaces); mapIt.More(); mapIt.Next())
        {
            ShapeFix_Face faceFixer(TopoDS::Face(mapIt.Value()));
            faceFixer.Perform();
        }
        workShell = TopoDS::Shell(edgeFuse.Shape());
        // update the list of modifications
        TopTools_DataMapOfShapeShape faceMap;
        edgeFuse.Faces(faceMap);
        for (mapIt.Initialize(faceMap); mapIt.More(); mapIt.Next())
        {
            bool isModifiedFace = false;
            for (std::vector<ShapePairType>::iterator it = modifiedShapes.begin(); it != modifiedShapes.end(); ++it)
            {
                if (mapIt.Key().IsSame(it->second)) {
                    // Note: IsEqual() for some reason does not work
                    it->second = mapIt.Value();
                    isModifiedFace = true;
                }
            }
            if (!isModifiedFace)
            {
                // Catch faces that were not united but whose boundary was changed (probably because
                // several adjacent faces were united)
                // See https://sourceforge.net/apps/mantisbt/free-cad/view.php?id=873
                modifiedShapes.push_back(std::make_pair(mapIt.Key(), mapIt.Value()));
            }
        }
        // Handle edges that were fused. See https://sourceforge.net/apps/mantisbt/free-cad/view.php?id=873
        TopTools_DataMapOfIntegerListOfShape oldEdges;
        TopTools_DataMapOfIntegerShape newEdges;
        edgeFuse.Edges(oldEdges);
        edgeFuse.ResultEdges(newEdges);
        TopTools_DataMapIteratorOfDataMapOfIntegerListOfShape edgeMapIt;
        for (edgeMapIt.Initialize(oldEdges); edgeMapIt.More(); edgeMapIt.Next())
        {
            const TopTools_ListOfShape& edges = edgeMapIt.Value();
            int idx = edgeMapIt.Key();
            TopTools_ListIteratorOfListOfShape edgeIt;
            for (edgeIt.Initialize(edges); edgeIt.More(); edgeIt.Next())
            {
                modifiedShapes.push_back(std::make_pair(edgeIt.Value(), newEdges(idx)));
            }
            // TODO: Handle vertices that have disappeared in the fusion of the edges
        }
    }
    return true;
}
예제 #29
0
//=======================================================================
// function: BuildSplitFaces
// purpose:
//=======================================================================
void GEOMAlgo_Builder::BuildSplitFaces()
{
  const NMTDS_ShapesDataStructure& aDS=*myPaveFiller->DS();
  NMTTools_PaveFiller* pPF=myPaveFiller;
  NMTDS_InterfPool* pIP=pPF->IP();
  BOPTools_CArray1OfSSInterference& aFFs=pIP->SSInterferences();
  const Handle(IntTools_Context)& aCtx= pPF->Context();
  //
  Standard_Boolean bToReverse, bIsClosed, bIsDegenerated;
  Standard_Integer i, aNb, aNbF, nF;
  TopTools_MapOfShape aMFence;
  TColStd_IndexedMapOfInteger aMFP;
  TopExp_Explorer anExp;
  TopoDS_Face aFF;
  TopoDS_Edge aSp, aEE;
  TopTools_ListIteratorOfListOfShape aIt;
  TopAbs_Orientation anOriF, anOriE;
  //
  mySplitFaces.Clear();
  //
  // 1. Select Faces to process (MFP)
  aNb=aDS.NumberOfShapesOfTheObject();
  for (i=1; i<=aNb; ++i) {
    const TopoDS_Shape& aF=aDS.Shape(i);
    if (aF.ShapeType()!=TopAbs_FACE) {
      continue;
    }
    if (!aMFence.Add(aF)) {
      continue;
    }
    //
    if (myInParts.Contains(aF)) {
      aMFP.Add(i);
      continue;
    }
    //
    anExp.Init(aF, TopAbs_EDGE);
    for (; anExp.More(); anExp.Next()) {
      const TopoDS_Shape& aE=anExp.Current();
      if (myImages.HasImage(aE)) {
        aMFP.Add(i);
        break;
      }
    }
    //
    //===
    {
      Standard_Integer aNbFFs, aNbSE, j, n1, n2;
      //
      aNbFFs=aFFs.Extent();
      for (j=1; j<=aNbFFs; ++j) {
        BOPTools_SSInterference& aFFj=aFFs(j);
        aFFj.Indices(n1, n2);
        if (!(n1==i || n2==i)) {
          continue;
        }
        //
        const TColStd_ListOfInteger& aLSE=aFFj.SharedEdges();
        aNbSE=aLSE.Extent();
        if (aNbSE) {
          aMFP.Add(i);
          break;
        }
      }
    }
    //===
    //
  }// for (i=1; i<=aNb; ++i)
  //
  // 2. ProcessFaces
  aNbF=aMFP.Extent();
  for (i=1; i<=aNbF; ++i) {
    nF=aMFP(i);
    const TopoDS_Face& aF=TopoDS::Face(aDS.Shape(nF));
    anOriF=aF.Orientation();
    aFF=aF;
    aFF.Orientation(TopAbs_FORWARD);
    //
    aMFence.Clear();
    //
    // 2.1. Fill WES
    GEOMAlgo_WireEdgeSet aWES;
    aWES.SetFace(aFF);
    //
    //  2.1.1. Add Split parts
    anExp.Init(aFF, TopAbs_EDGE);
    for (; anExp.More(); anExp.Next()) {
      const TopoDS_Edge& aE=TopoDS::Edge(anExp.Current());
      anOriE=aE.Orientation();
      //
      if (!myImages.HasImage(aE)) {
        if (anOriE==TopAbs_INTERNAL) {
          aEE=aE;
          aEE.Orientation(TopAbs_FORWARD);
          aWES.AddStartElement(aEE);
          aEE.Orientation(TopAbs_REVERSED);
          aWES.AddStartElement(aEE);
        }
        else {
          aWES.AddStartElement(aE);
        }
        continue;
      }
      //
      bIsDegenerated=BRep_Tool::Degenerated(aE);
      //modified by NIZNHY-PKV Wed Mar 07 07:46:09 2012f
      bIsClosed=IsClosed(aE, aF);
      //bIsClosed=BRep_Tool::IsClosed(aE, aF);
      //modified by NIZNHY-PKV Wed Mar 07 07:46:13 2012t
      //
      const TopTools_ListOfShape& aLIE=myImages.Image(aE);
      aIt.Initialize(aLIE);
      for (; aIt.More(); aIt.Next()) {
        aSp=TopoDS::Edge(aIt.Value());
        //
        if (bIsDegenerated) {
          aSp.Orientation(anOriE);
          aWES.AddStartElement(aSp);
          continue;
        }
        //
        if (anOriE==TopAbs_INTERNAL) {
          aSp.Orientation(TopAbs_FORWARD);
          aWES.AddStartElement(aSp);
          aSp.Orientation(TopAbs_REVERSED);
          aWES.AddStartElement(aSp);
          continue;
        }
        //
        if (bIsClosed){
          if (aMFence.Add(aSp)) {
            //
            if (!BRep_Tool::IsClosed(aSp, aF)){
              BOPTools_Tools3D::DoSplitSEAMOnFace(aSp, aF);
            }
            //
            aSp.Orientation(TopAbs_FORWARD);
            aWES.AddStartElement(aSp);
            aSp.Orientation(TopAbs_REVERSED);
            aWES.AddStartElement(aSp);
          }
          continue;
        }// if (aMFence.Add(aSp))
        //
        aSp.Orientation(anOriE);
        bToReverse=BOPTools_Tools3D::IsSplitToReverse1(aSp, aE, aCtx);
        if (bToReverse) {
          aSp.Reverse();
        }
        aWES.AddStartElement(aSp);
      }// for (; aIt.More(); aIt.Next()) {
    }// for (; anExp.More(); anExp.Next()) {
    //
    // 2.1.2. Add In2D Parts
    if (myInParts.Contains(aF)) {
      const TopTools_ListOfShape& aLE=myInParts.FindFromKey(aF);
      aIt.Initialize(aLE);
      for (; aIt.More(); aIt.Next()) {
        aSp=TopoDS::Edge(aIt.Value());
        //
        aSp.Orientation(TopAbs_FORWARD);
        aWES.AddStartElement(aSp);
        //
        aSp.Orientation(TopAbs_REVERSED);
        aWES.AddStartElement(aSp);
      }
    }
    //
    // 2.2. Build images Faces
    TopTools_ListOfShape aLFR;
    GEOMAlgo_ShapeSet aS1, aS2;
    //
    const TopTools_ListOfShape& aSE=aWES.StartElements();
    aS1.Add(aSE);
    aS2.Add(aFF, TopAbs_EDGE);
    if (aS1.IsEqual(aS2)) {
      aLFR.Append(aF);
    }
    else {
      GEOMAlgo_BuilderFace aBF;
      //
      aBF.SetFace(aFF);
      aBF.SetContext(aCtx);
      aBF.SetShapes(aSE);
      // <-DEB
      aBF.Perform();
      //
      const TopTools_ListOfShape& aLF=aBF.Areas();
      aIt.Initialize(aLF);
      for (; aIt.More(); aIt.Next()) {
        TopoDS_Shape& aFR=aIt.Value();
        if (anOriF==TopAbs_REVERSED) {
          aFR.Orientation(TopAbs_REVERSED);
        }
        aLFR.Append(aFR);
      }
    }
    //
    // 2.3. Collect draft images Faces
    mySplitFaces.Bind(aF, aLFR);
  }//for (i=1; i<=aNbF; ++i)
}
예제 #30
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;
}