//=======================================================================
//function : PrepareHistory
//purpose  :
//=======================================================================
void GEOMAlgo_Builder::PrepareHistory()
{
    if(myShape.IsNull()) {
        return;
    }
    //
    Standard_Boolean bHasImage, bContainsSD;
    TopAbs_ShapeEnum aType;
    TopTools_MapOfShape aMS;
    TopTools_ListIteratorOfListOfShape aIt;
    TopTools_MapIteratorOfMapOfShape aItM;
    //
    // 1. Clearing
    GEOMAlgo_BuilderShape::PrepareHistory();
    //
    // 2. myMapShape - all shapes of result with theirs sub-shapes
    MapShapes(myShape, myMapShape);
    //
    // 3. MS - all argument shapes with theirs sub-shapes
    aIt.Initialize(myShapes);
    for (; aIt.More(); aIt.Next()) {
        const TopoDS_Shape& aSx=aIt.Value();
        MapShapes(aSx, aMS);
    }
    //
    // 4. Treatment
    aItM.Initialize(aMS);
    for (; aItM.More(); aItM.Next()) {
        const TopoDS_Shape& aSx=aItM.Key();
        aType=aSx.ShapeType();
        //modified by NIZNHY-PKV Thu Dec  7 11:34:05 2006f
        //
        // 4.1 .myImagesResult
        TopTools_ListOfShape aLSx;
        //
        bHasImage=myImages.HasImage(aSx);
        if (!bHasImage) {
            if (myMapShape.Contains(aSx)) {
                aLSx.Append(aSx);
                myImagesResult.Add(aSx, aLSx);
            }
        }
        else {
            const TopTools_ListOfShape& aLSp=myImages.Image(aSx);
            aIt.Initialize(aLSp);
            for (; aIt.More(); aIt.Next()) {
                const TopoDS_Shape& aSp=aIt.Value();
                if (myMapShape.Contains(aSp)) {
                    aLSx.Append(aSp);
                }
            }
            myImagesResult.Add(aSx, aLSx);
        }
        //
        //modified by NIZNHY-PKV Thu Dec  7 11:34:10 2006t
        //
        // 4.2 As it was
        if (!myHasDeleted) {
            myHasDeleted=IsDeleted(aSx);//xx
        }
        //
        if (!myHasGenerated || !myHasModified) {
            if (aType==TopAbs_EDGE   || aType==TopAbs_FACE ||
                    aType==TopAbs_VERTEX || aType==TopAbs_SOLID) {
                //modified by NIZNHY-PKV Thu Dec  7 11:53:01 2006f
                //bHasImage=myImages.HasImage(aSx);
                //modified by NIZNHY-PKV Thu Dec  7 11:53:04 2006t
                if (bHasImage) {
                    const TopTools_ListOfShape& aLSp=myImages.Image(aSx);
                    aIt.Initialize(aLSp);
                    for (; aIt.More(); aIt.Next()) {
                        const TopoDS_Shape& aSp=aIt.Value();
                        //
                        if (myMapShape.Contains(aSp)) {
                            bContainsSD=mySameDomainShapes.Contains(aSp);
                            //
                            if (!myHasGenerated) {
                                if (bContainsSD) {
                                    myHasGenerated=Standard_True;
                                }
                            }
                            if (!myHasModified) {
                                if (!bContainsSD) {
                                    myHasModified=Standard_True;
                                }
                            }
                        } // if (myMapShape.Contains(aSp))
                    }
                }
            }
        }
    }

}
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 {
            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();
        }
        catch (Standard_Failure) {
            if (shape._Shape.ShapeType() == TopAbs_EDGE)
                path = shape._Shape;
            else if (shape._Shape.ShapeType() == TopAbs_WIRE)
                path = shape._Shape;
            else
                return new App::DocumentObjectExecReturn("Spine is neither an edge nor a wire.");
        }
    }

    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.");
            const TopoDS_Shape& shape = static_cast<Part::Feature*>(*it)->Shape.getValue();
            if (shape.IsNull())
                return new App::DocumentObjectExecReturn("Linked shape is invalid.");
            // 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.
            // https://sourceforge.net/apps/phpbb/free-cad/viewtopic.php?f=10&t=2673&sid=fbcd2ff4589f0b2f79ed899b0b990648#p20268
            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 nor wire.");
            }
        }

        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());
    }
}
Esempio n. 3
0
//=======================================================================
//function : SortShapes
//purpose  :
//=======================================================================
void GEOMUtils::SortShapes (TopTools_ListOfShape& SL,
                            const Standard_Boolean isOldSorting)
{
#ifdef STD_SORT_ALGO
  std::vector<TopoDS_Shape> aShapesVec;
  aShapesVec.reserve(SL.Extent());

  TopTools_ListIteratorOfListOfShape it (SL);
  for (; it.More(); it.Next()) {
    aShapesVec.push_back(it.Value());
  }
  SL.Clear();

  CompareShapes shComp (isOldSorting);
  std::stable_sort(aShapesVec.begin(), aShapesVec.end(), shComp);
  //std::sort(aShapesVec.begin(), aShapesVec.end(), shComp);

  std::vector<TopoDS_Shape>::const_iterator anIter = aShapesVec.begin();
  for (; anIter != aShapesVec.end(); ++anIter) {
    SL.Append(*anIter);
  }
#else
  // old implementation
  Standard_Integer MaxShapes = SL.Extent();
  TopTools_Array1OfShape  aShapes (1,MaxShapes);
  TColStd_Array1OfInteger OrderInd(1,MaxShapes);
  TColStd_Array1OfReal    MidXYZ  (1,MaxShapes); //X,Y,Z;
  TColStd_Array1OfReal    Length  (1,MaxShapes); //X,Y,Z;

  // Computing of CentreOfMass
  Standard_Integer Index;
  GProp_GProps GPr;
  gp_Pnt GPoint;
  TopTools_ListIteratorOfListOfShape it(SL);
  for (Index=1;  it.More();  Index++)
  {
    TopoDS_Shape S = it.Value();
    SL.Remove( it ); // == it.Next()
    aShapes(Index) = S;
    OrderInd.SetValue (Index, Index);
    if (S.ShapeType() == TopAbs_VERTEX) {
      GPoint = BRep_Tool::Pnt( TopoDS::Vertex( S ));
      Length.SetValue( Index, (Standard_Real) S.Orientation());
    }
    else {
      // BEGIN: fix for Mantis issue 0020842
      if (isOldSorting) {
        BRepGProp::LinearProperties (S, GPr);
      }
      else {
        if (S.ShapeType() == TopAbs_EDGE || S.ShapeType() == TopAbs_WIRE) {
          BRepGProp::LinearProperties (S, GPr);
        }
        else if (S.ShapeType() == TopAbs_FACE || S.ShapeType() == TopAbs_SHELL) {
          BRepGProp::SurfaceProperties(S, GPr);
        }
        else {
          BRepGProp::VolumeProperties(S, GPr);
        }
      }
      // END: fix for Mantis issue 0020842
      GPoint = GPr.CentreOfMass();
      Length.SetValue(Index, GPr.Mass());
    }
    MidXYZ.SetValue(Index, GPoint.X()*999.0 + GPoint.Y()*99.0 + GPoint.Z()*0.9);
    //cout << Index << " L: " << Length(Index) << "CG: " << MidXYZ(Index) << endl;
  }

  // Sorting
  Standard_Integer aTemp;
  Standard_Boolean exchange, Sort = Standard_True;
  Standard_Real    tol = Precision::Confusion();
  while (Sort)
  {
    Sort = Standard_False;
    for (Index=1; Index < MaxShapes; Index++)
    {
      exchange = Standard_False;
      Standard_Real dMidXYZ = MidXYZ(OrderInd(Index)) - MidXYZ(OrderInd(Index+1));
      Standard_Real dLength = Length(OrderInd(Index)) - Length(OrderInd(Index+1));
      if ( dMidXYZ >= tol ) {
//         cout << "MidXYZ: " << MidXYZ(OrderInd(Index))<< " > " <<MidXYZ(OrderInd(Index+1))
//              << " d: " << dMidXYZ << endl;
        exchange = Standard_True;
      }
      else if ( Abs(dMidXYZ) < tol && dLength >= tol ) {
//         cout << "Length: " << Length(OrderInd(Index))<< " > " <<Length(OrderInd(Index+1))
//              << " d: " << dLength << endl;
        exchange = Standard_True;
      }
      else if ( Abs(dMidXYZ) < tol && Abs(dLength) < tol &&
                aShapes(OrderInd(Index)).ShapeType() <= TopAbs_FACE) {
        // PAL17233
        // equal values possible on shapes such as two halves of a sphere and
        // a membrane inside the sphere
        Bnd_Box box1,box2;
        BRepBndLib::Add( aShapes( OrderInd(Index) ), box1 );
        if ( box1.IsVoid() ) continue;
        BRepBndLib::Add( aShapes( OrderInd(Index+1) ), box2 );
        Standard_Real dSquareExtent = box1.SquareExtent() - box2.SquareExtent();
        if ( dSquareExtent >= tol ) {
//           cout << "SquareExtent: " << box1.SquareExtent()<<" > "<<box2.SquareExtent() << endl;
          exchange = Standard_True;
        }
        else if ( Abs(dSquareExtent) < tol ) {
          Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, val1, val2;
          box1.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
          val1 = (aXmin+aXmax)*999 + (aYmin+aYmax)*99 + (aZmin+aZmax)*0.9;
          box2.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
          val2 = (aXmin+aXmax)*999 + (aYmin+aYmax)*99 + (aZmin+aZmax)*0.9;
          //exchange = val1 > val2;
          if ((val1 - val2) >= tol) {
            exchange = Standard_True;
          }
          //cout << "box: " << val1<<" > "<<val2 << endl;
        }
      }

      if (exchange)
      {
//         cout << "exchange " << Index << " & " << Index+1 << endl;
        aTemp = OrderInd(Index);
        OrderInd(Index) = OrderInd(Index+1);
        OrderInd(Index+1) = aTemp;
        Sort = Standard_True;
      }
    }
  }

  for (Index=1; Index <= MaxShapes; Index++)
    SL.Append( aShapes( OrderInd(Index) ));
#endif
}
Esempio n. 4
0
//=======================================================================
// function: MakeConnexityBlock.
// purpose: 
//=======================================================================
  void GEOMAlgo_Tools3D::MakeConnexityBlock (const TopTools_ListOfShape& theLFIn,
                                             const TopTools_IndexedMapOfShape& theMEAvoid,
                                             TopTools_ListOfShape& theLCB)
{
  Standard_Integer  aNbF, aNbAdd1;
  TopExp_Explorer aExp;
  TopTools_IndexedDataMapOfShapeListOfShape aMEF;
  TopTools_MapIteratorOfMapOfShape aItM, aItM1;
  TopTools_MapOfShape aMCB, aMAdd, aMAdd1;
  TopTools_ListIteratorOfListOfShape aIt;
  //
  // 1. aMEF
  aNbF=theLFIn.Extent();
  aIt.Initialize(theLFIn);
  for (; aIt.More(); aIt.Next()) {
    const TopoDS_Shape& aF=aIt.Value();      
    TopExp::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, aMEF);
  }
  //
  // 2. aMCB
  const TopoDS_Shape& aF1=theLFIn.First();
  aMAdd.Add(aF1);
  //
  while(1) {
    aMAdd1.Clear();
    aItM.Initialize(aMAdd);
    for (; aItM.More(); aItM.Next()) {
      const TopoDS_Shape& aF=aItM.Key();
      //
      //aMAdd1.Clear();
      aExp.Init(aF, TopAbs_EDGE);
      for (; aExp.More(); aExp.Next()) {
        const TopoDS_Shape& aE=aExp.Current();
        if (theMEAvoid.Contains(aE)){
          continue;
        }
        //
        const TopTools_ListOfShape& aLF=aMEF.FindFromKey(aE);
        aIt.Initialize(aLF);
        for (; aIt.More(); aIt.Next()) {
          const TopoDS_Shape& aFx=aIt.Value();
          if (aFx.IsSame(aF)) {
            continue;
          }
          if (aMCB.Contains(aFx)) {
            continue;
          }
          aMAdd1.Add(aFx);
        }
      }//for (; aExp.More(); aExp.Next()){
      aMCB.Add(aF);
    }// for (; aItM.More(); aItM.Next()) {
    //
    aNbAdd1=aMAdd1.Extent();
    if (!aNbAdd1) {
      break;
    }
    //
    aMAdd.Clear();
    aItM1.Initialize(aMAdd1);
    for (; aItM1.More(); aItM1.Next()) {
      const TopoDS_Shape& aFAdd=aItM1.Key();
      aMAdd.Add(aFAdd);
    }
    //
  }//while(1) {
  
  //
  aNbF=aMCB.Extent();
  aItM.Initialize(aMCB);
  for (; aItM.More(); aItM.Next()) {
    const TopoDS_Shape& aF=aItM.Key();
    theLCB.Append(aF);
  }
}
Esempio n. 5
0
//=======================================================================
//function : FindFacePairs
//purpose  : 
//=======================================================================
Standard_Boolean FindFacePairs (const TopoDS_Edge& theE,
                                const TopTools_ListOfShape& thLF,
                                NMTTools_ListOfCoupleOfShape& theLCFF)
{
  Standard_Boolean bFound;
  Standard_Integer i, aNbCEF;
  TopAbs_Orientation aOr, aOrC;
  TopTools_MapOfShape aMFP;
  TopoDS_Face aF1, aF2;
  TopoDS_Edge aEL, aE1;
  TopTools_ListIteratorOfListOfShape aItLF;
  NMTTools_CoupleOfShape aCEF, aCFF;
  NMTTools_ListOfCoupleOfShape aLCEF, aLCEFx;
  NMTTools_ListIteratorOfListOfCoupleOfShape aIt;
  //
  bFound=Standard_True;
  //
  // Preface aLCEF
  aItLF.Initialize(thLF);
  for (; aItLF.More(); aItLF.Next()) { 
    const TopoDS_Face& aFL=TopoDS::Face(aItLF.Value());
    //
    bFound=GEOMAlgo_Tools3D::GetEdgeOnFace(theE, aFL, aEL);
    if (!bFound) {
      return bFound; // it can not be so
    }
    //
    aCEF.SetShape1(aEL);
    aCEF.SetShape2(aFL);
    aLCEF.Append(aCEF);
  }
  //
  aNbCEF=aLCEF.Extent();
  while(aNbCEF) {
    //
    // aLCEFx
    aLCEFx.Clear();
    aIt.Initialize(aLCEF);
    for (i=0; aIt.More(); aIt.Next(), ++i) {
      const NMTTools_CoupleOfShape& aCSx=aIt.Value();
      const TopoDS_Shape& aEx=aCSx.Shape1();
      const TopoDS_Shape& aFx=aCSx.Shape2();
      //
      aOr=aEx.Orientation();
      //
      if (!i) {
        aOrC=TopAbs::Reverse(aOr);
        aE1=TopoDS::Edge(aEx);
        aF1=TopoDS::Face(aFx);
        aMFP.Add(aFx);
        continue;
      }
      //
      if (aOr==aOrC) {
        aLCEFx.Append(aCSx);
        aMFP.Add(aFx);
      }
    }
    //
    // F2
    GEOMAlgo_Tools3D::GetFaceOff(aE1, aF1, aLCEFx, aF2);
    //
    aCFF.SetShape1(aF1);
    aCFF.SetShape2(aF2);
    theLCFF.Append(aCFF);
    //
    aMFP.Add(aF1);
    aMFP.Add(aF2);
    //
    // refine aLCEF
    aLCEFx.Clear();
    aLCEFx=aLCEF;
    aLCEF.Clear();
    aIt.Initialize(aLCEFx);
    for (; aIt.More(); aIt.Next()) {
      const NMTTools_CoupleOfShape& aCSx=aIt.Value();
      const TopoDS_Shape& aFx=aCSx.Shape2();
      if (!aMFP.Contains(aFx)) {
        aLCEF.Append(aCSx);
      }
    }
    //
    aNbCEF=aLCEF.Extent();
  }//while(aNbCEF) {
  //
  return bFound;
}
//=======================================================================
//function :PerformShapesToAvoid
//purpose  : 
//=======================================================================
  void GEOMAlgo_BuilderFace::PerformShapesToAvoid()
{
  Standard_Boolean bFound;
  Standard_Integer i, iCnt, aNbV, aNbE;
  TopTools_IndexedDataMapOfShapeListOfShape aMVE;
  TopTools_ListIteratorOfListOfShape aIt;
  //
  myShapesToAvoid.Clear();
  //
  iCnt=0;
  while (1) {
    ++iCnt;
    bFound=Standard_False;
    //
    // 1. MEF
    aMVE.Clear();
    aIt.Initialize (myShapes);
    for (; aIt.More(); aIt.Next()) {
      const TopoDS_Shape& aE=aIt.Value();
      if (!myShapesToAvoid.Contains(aE)) {
	TopExp::MapShapesAndAncestors(aE, TopAbs_VERTEX, TopAbs_EDGE, aMVE);
      }
//       else {
//         int a=0;
//       }
    }
    aNbV=aMVE.Extent();
    //
    // 2. myEdgesToAvoid
    for (i=1; i<=aNbV; ++i) {
      const TopoDS_Vertex& aV=TopoDS::Vertex(aMVE.FindKey(i));
      //
      TopTools_ListOfShape& aLE=aMVE.ChangeFromKey(aV);
      aNbE=aLE.Extent();
      if (!aNbE) {
	continue;
      }
      //
      const TopoDS_Edge& aE1=TopoDS::Edge(aLE.First());
      if (aNbE==1) {
	if (BRep_Tool::Degenerated(aE1)) {
	  continue;
	}
	if (aV.Orientation()==TopAbs_INTERNAL) {
	  continue;
	}
	bFound=Standard_True;
	myShapesToAvoid.Add(aE1);
      }
      else if (aNbE==2) {
	const TopoDS_Edge& aE2=TopoDS::Edge(aLE.Last());
	if (aE2.IsSame(aE1)) {
	  TopoDS_Vertex aV1x, aV2x;
	  //
	  TopExp::Vertices(aE1, aV1x, aV2x);
	  if (aV1x.IsSame(aV2x)) {
	    continue;
	  }
	  bFound=Standard_True;
	  myShapesToAvoid.Add(aE1);
	  myShapesToAvoid.Add(aE2);
	}
      }
    }// for (i=1; i<=aNbE; ++i) {
    //
    if (!bFound) {
      break;
    }
    //
  }//while (1) 
  //printf(" EdgesToAvoid=%d, iCnt=%d\n", EdgesToAvoid.Extent(), iCnt);
}  
Esempio n. 7
0
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.pnums[0] = prevNgId;
          seg.pnums[1] = 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.pnums[0], seg.pnums[1]);
            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;
}
//=======================================================================
//function : CheckGProps
//purpose  :
//=======================================================================
void GEOMAlgo_GetInPlace::CheckGProps(const TopoDS_Shape& aS1)
{
  Standard_Boolean bOnlyClosed;
  Standard_Integer iDim, aNbS2;
  Standard_Real aMass1, aMass2, aD2, aTolCG2, dM;
  TopAbs_ShapeEnum  aType1;
  gp_Pnt aCG1, aCG2;
  TopoDS_Iterator aIt;
  TopoDS_Compound aC2;
  BRep_Builder aBB;
  TopTools_ListIteratorOfListOfShape aItLS;
  //
  myErrorStatus=0;
  //
  aType1=aS1.ShapeType();
  if (aType1==TopAbs_COMPOUND) {
    aIt.Initialize(aS1);
    for(; aIt.More(); aIt.Next()) {
      const TopoDS_Shape& aS1x=aIt.Value();
      CheckGProps(aS1x);
      if (!myFound) {
	return;
      }
    }
  }
  //
  iDim=Dimension(aType1);
  //
  if (!myImages.IsBound(aS1)) {
    // it should not be.
    return;
  }
  const TopTools_ListOfShape& aLS2=myImages.Find(aS1);
  aNbS2=aLS2.Extent();
  if (!aNbS2) {
    // it should not be.
    return;
  }
  //
  aBB.MakeCompound(aC2);
  aItLS.Initialize(aLS2);
  for (; aItLS.More(); aItLS.Next()) {
    const TopoDS_Shape& aS2x=aItLS.Value();
    aBB.Add(aC2, aS2x);
  }
  //-------------------------
  GProp_GProps aG1, aG2;
  //
  aTolCG2=myTolCG*myTolCG;
  bOnlyClosed=Standard_False;
  //
  if (iDim==0) {
    PointProperties(aS1, aG1);
    PointProperties(aC2, aG2);
  }
  else if (iDim==1) {
    BRepGProp::LinearProperties(aS1, aG1);
    BRepGProp::LinearProperties(aC2, aG2);
  }
  else if (iDim==2) {
    BRepGProp::SurfaceProperties(aS1, aG1);
    BRepGProp::SurfaceProperties(aC2, aG2);
  }
  else if (iDim==3) {
    BRepGProp::VolumeProperties(aS1, aG1, bOnlyClosed);
    BRepGProp::VolumeProperties(aC2, aG2, bOnlyClosed);
  }
  //
  aMass1=aG1.Mass();
  aMass2=aG2.Mass();
  aCG1=aG1.CentreOfMass();
  aCG2=aG2.CentreOfMass();
  //
  dM=fabs(aMass1-aMass2);
  if (aMass1 > myTolMass) {
    dM=dM/aMass1;
  }
  //
  aD2=aCG1.SquareDistance(aCG2);
  //
  if ((dM > myTolMass) || (aD2 > aTolCG2)) {
    myFound=Standard_False;
    return;
  }
  myFound=Standard_True;
}
//=======================================================================
//function : DetectVertices
//purpose  : 
//=======================================================================
void GEOMAlgo_GlueDetector::DetectVertices()
{
  Standard_Integer j, i, aNbV, aNbVSD;
  Standard_Real aTolV;
  gp_Pnt aPV;
  TColStd_ListIteratorOfListOfInteger aIt;
  TopoDS_Shape aVF;
  TopTools_IndexedMapOfShape aMV;
  TopTools_MapOfShape aMVProcessed;
  TopTools_ListIteratorOfListOfShape aItS;
  TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItIm;
  TopTools_DataMapOfShapeListOfShape aMVV;
  GEOMAlgo_IndexedDataMapOfIntegerShape aMIS;
  NMTDS_IndexedDataMapOfShapeBndSphere aMSB;
  //
  NMTDS_BndSphereTreeSelector aSelector;
  NMTDS_BndSphereTree aBBTree;
  NCollection_UBTreeFiller <Standard_Integer, NMTDS_BndSphere> aTreeFiller(aBBTree);
  //
  myErrorStatus=0;
  //
  TopExp::MapShapes(myArgument, TopAbs_VERTEX, aMV);
  aNbV=aMV.Extent();
  if (!aNbV) {
    myErrorStatus=2; // no vertices in source shape
    return;
  }
  //
  for (i=1; i<=aNbV; ++i) {
    NMTDS_BndSphere aBox;
    //
    const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&aMV(i));
    aPV=BRep_Tool::Pnt(aV);
    aTolV=BRep_Tool::Tolerance(aV);
    //
    aBox.SetGap(myTolerance);
    aBox.SetCenter(aPV);
    aBox.SetRadius(aTolV);
    //
    aTreeFiller.Add(i, aBox);
    //
    aMIS.Add(i, aV);
    aMSB.Add(aV, aBox); 
  }
  //
  aTreeFiller.Fill();
  //
  //---------------------------------------------------
  // Chains
  for (i=1; i<=aNbV; ++i) {
    const TopoDS_Shape& aV=aMV(i);
    //
    if (aMVProcessed.Contains(aV)) {
      continue;
    }
    //
    Standard_Integer aNbIP, aIP, aNbIP1, aIP1;
    TopTools_ListOfShape aLVSD;
    TColStd_MapOfInteger aMIP, aMIP1, aMIPC;
    TColStd_MapIteratorOfMapOfInteger aIt1;
    //
    aMIP.Add(i);
    while(1) {
      aNbIP=aMIP.Extent();
      aIt1.Initialize(aMIP);
      for(; aIt1.More(); aIt1.Next()) {
	aIP=aIt1.Key();
	if (aMIPC.Contains(aIP)) {
	  continue;
	}
	//
	const TopoDS_Shape& aVP=aMIS.FindFromKey(aIP);
	const NMTDS_BndSphere& aBoxVP=aMSB.FindFromKey(aVP);
	//
	aSelector.Clear();
	aSelector.SetBox(aBoxVP);
	//
	aNbVSD=aBBTree.Select(aSelector);
	if (!aNbVSD) {
	  continue;  // it shoild not be so [at least IP itself]    
	}
	//
	const TColStd_ListOfInteger& aLI=aSelector.Indices();
	aIt.Initialize(aLI);
	for (; aIt.More(); aIt.Next()) {
	  aIP1=aIt.Value();
	  if (aMIP.Contains(aIP1)) {
	    continue;
	  }
	  aMIP1.Add(aIP1);
	} //for (; aIt.More(); aIt.Next()) {
      }//for(; aIt1.More(); aIt1.Next()) {
      //
      aNbIP1=aMIP1.Extent();
      if (!aNbIP1) {
	break;
      }
      //
      aIt1.Initialize(aMIP);
      for(; aIt1.More(); aIt1.Next()) {
	aIP=aIt1.Key();
	aMIPC.Add(aIP);
      }
      //
      aMIP.Clear();
      aIt1.Initialize(aMIP1);
      for(; aIt1.More(); aIt1.Next()) {
	aIP=aIt1.Key();
	aMIP.Add(aIP);
      }
      aMIP1.Clear();
    }// while(1)
    //
    // Fill myImages
    aNbIP=aMIPC.Extent();
    //
    if (!aNbIP) {// no SD vertices is found
      aMVProcessed.Add(aV);
      continue;
    }
    //else { // SD vertices founded [ aMIPC ]
    aIt1.Initialize(aMIPC);
    for(j=0; aIt1.More(); aIt1.Next(), ++j) {
      aIP=aIt1.Key();
      const TopoDS_Shape& aVP=aMIS.FindFromKey(aIP);
      if (!j) {
	aVF=aVP;
      }
      aLVSD.Append(aVP);
      aMVProcessed.Add(aVP);
    }
    //}
    myImages.Bind(aVF, aLVSD);
  }// for (i=1; i<=aNbV; ++i) {
  //------------------------------
  // 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);
      }
    }
  }
}
Esempio n. 10
0
//----------------------------------------------------------------
// Function: TopoDS_Shape level function to update the core Body
//           for any Boolean operation of the body.
// Author: Jane Hu
//----------------------------------------------------------------
CubitStatus OCCBody::update_OCC_entity(TopoDS_Shape& old_shape,
                                       TopoDS_Shape& new_shape,
                                       BRepBuilderAPI_MakeShape *op,
                                       LocOpe_SplitShape* sp)
{
  //set the Shells
  TopTools_IndexedMapOfShape M;
  TopExp::MapShapes(old_shape, TopAbs_SOLID, M);
  TopTools_IndexedMapOfShape M_new;
  TopExp::MapShapes(new_shape, TopAbs_SOLID, M_new);
  TopTools_ListOfShape shapes;
  TopoDS_Shape shape;

  CubitBoolean updated = CUBIT_FALSE;	
  if(!old_shape.IsNull() && old_shape.ShapeType() == TopAbs_COMPOUND && 
     !new_shape.IsNull() && new_shape.ShapeType() == TopAbs_COMPOUND &&
     !old_shape.IsSame(new_shape))
  {
    //By updating underling solids, shells etc., the old_shape will get changed.
    //trying to make sure the the number of each entity in the old and new 
    //shapes are the same, which means that nothing is delete, that we can 
    //update the map here. Otherwise, when deleting solids, it'll delete the
    //the old body and create new body. This is Ok for general boolean operation    //except imprint when booleans are called, usually the original body are
    // supposed to be kept. 
    updated = CUBIT_TRUE;
    OCCQueryEngine::instance()->update_OCC_map(old_shape, new_shape);
  }
 
  DLIList<int> new_solid_nums;
  DLIList<int> unfound_nums;
  for(int ii=1; ii<=M.Extent(); ii++)
  {
    TopoDS_Solid solid = TopoDS::Solid(M(ii));

    TopTools_ListOfShape shapes;
    if(op)
    {
      shapes.Assign(op->Modified(solid));
      if(shapes.Extent() == 0)
         shapes.Assign(op->Generated(solid));
    }
    else if(sp)
      shapes.Assign(sp->DescendantShapes(solid));

    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(solid, shape);
      } 
      shape = shapes.First();
    }

    else if(op->IsDeleted(solid))
    {
       if (M_new.Extent()== 1 && ii == 1)
         shape = M_new(1);
       else if(M_new.Extent()== 1 && ii > 1)
         shape.Nullify();
       else if(M_new.Extent() > 1)
       {
         GProp_GProps myProps;
         BRepGProp::VolumeProperties(solid, myProps);
         double bf_mass = myProps.Mass();
         gp_Pnt old_center = myProps.CentreOfMass();
         CubitBoolean found = CUBIT_FALSE;
         for(int l = 1; l <= M_new.Extent(); l++)
         {
           BRepGProp::VolumeProperties(M_new(l), myProps);
           double af_mass = myProps.Mass();
           double dTol = OCCQueryEngine::instance()->get_sme_resabs_tolerance();
           if(fabs(bf_mass-af_mass) < dTol) //unchanged
           {
             gp_Pnt  new_center = myProps.CentreOfMass(); 
             if(new_center.IsEqual(old_center, dTol))
             {
               found = CUBIT_TRUE;
               shape = M_new(l);
               new_solid_nums.append(l);
               break;
             }
           }
         }
         if(!found)
         {
           unfound_nums.append(ii); 
           continue;
         }
       }
       else
         shape.Nullify();
    }
    else
    {
       shape = solid;
       continue;
    }

    if(shapes.Extent() > 0 || (op && op->IsDeleted(solid)))
      OCCLump::update_OCC_entity(solid, shape, op, sp);
  }

  if( unfound_nums.size() == 1 )
  {
    TopoDS_Solid solid = TopoDS::Solid(M(unfound_nums.get()));
    for(int kk = 1; kk <= M_new.Extent(); kk++)
    {
      if(!new_solid_nums.move_to(kk))
      {
        shape = M_new(kk);
        break;
      } 
    }
    OCCLump::update_OCC_entity(solid, shape, op, sp);
  }
  else if(unfound_nums.size() > 1)
  {
    shape.Nullify();
    for(int kk = 1; kk <=unfound_nums.size(); kk++)
    {
       TopoDS_Solid solid = TopoDS::Solid(M(unfound_nums.get_and_step()));
       OCCLump::update_OCC_entity(solid, shape, op, sp);
    }
  } 
  if(!old_shape.IsSame(new_shape) && !updated)
    OCCQueryEngine::instance()->update_OCC_map(old_shape, new_shape);
  return CUBIT_SUCCESS;
}
Esempio n. 11
0
//=======================================================================
// function: Perform
// purpose: 
//=======================================================================
  void GEOMAlgo_WireSplitter::Perform()
{
  myErrorStatus=2;
  myNothingToDo=Standard_True;

  Standard_Integer index, i, aNb, aCntIn, aCntOut;
  Standard_Boolean anIsIn;
  Standard_Real anAngle;
  
  BOP_ListOfEdgeInfo emptyInfo;
  TopTools_ListIteratorOfListOfShape anItList;
  //
  // 1.Filling mySmartMap
  mySmartMap.Clear();

  anItList.Initialize(myEdges);
  for (; anItList.More(); anItList.Next()) {
    const TopoDS_Edge& anEdge = TopoDS::Edge(anItList.Value());
    //
    if (!BOPTools_Tools2D::HasCurveOnSurface (anEdge, myFace)) {
      continue;
    }
    //
    TopExp_Explorer anExpVerts (anEdge, TopAbs_VERTEX);
    for (; anExpVerts.More(); anExpVerts.Next()) {
      const TopoDS_Shape& aVertex= anExpVerts.Current();

      index = mySmartMap.FindIndex(aVertex);
      if (!index) {
	index=mySmartMap.Add(aVertex, emptyInfo);
      }
      
      BOP_ListOfEdgeInfo& aListOfEInfo=mySmartMap(index);

      BOP_EdgeInfo aEInfo;
      aEInfo.SetEdge(anEdge);
      
      TopAbs_Orientation anOr=aVertex.Orientation();

      if (anOr==TopAbs_FORWARD) {
	aEInfo.SetInFlag(Standard_False);
      }

      else if (anOr==TopAbs_REVERSED) {
	aEInfo.SetInFlag(Standard_True);
      }

      aListOfEInfo.Append(aEInfo);
    }
  }
  //
  aNb=mySmartMap.Extent();
  //
  // 2. myNothingToDo 
  myNothingToDo=Standard_True;
  
  for (i=1; i<=aNb; i++) {
    aCntIn=0;
    aCntOut=0;
    const BOP_ListOfEdgeInfo& aLEInfo= mySmartMap(i);
    BOP_ListIteratorOfListOfEdgeInfo anIt(aLEInfo);
    for (; anIt.More(); anIt.Next()) {
      const BOP_EdgeInfo& anEdgeInfo=anIt.Value();
      anIsIn=anEdgeInfo.IsIn();
      if (anIsIn) {
	aCntIn++;
      }
      else {
	aCntOut++;
      }
    }
    if (aCntIn!=1 || aCntOut!=1) {
      myNothingToDo=Standard_False;
      break;
    }
  }
  //
  // Each vertex has one edge In and one - Out. Good. But it is not enought
  // to consider that nothing to do with this. We must check edges on TShape
  // coinsidence. If there are such edges there is something to do with.
  // 
  if (myNothingToDo) {
    Standard_Integer aNbE, aNbMapEE;
    TopTools_IndexedDataMapOfShapeListOfShape aMapEE;
    aNbE=myEdges.Extent();
    
    anItList.Initialize(myEdges);
    for (; anItList.More(); anItList.Next()) {
      const TopoDS_Shape& aE = anItList.Value();
      
      if (!aMapEE.Contains(aE)) {
	TopTools_ListOfShape aLEx;
	aLEx.Append(aE);
	aMapEE.Add(aE, aLEx);
      }
      else {
	TopTools_ListOfShape& aLEx=aMapEE.ChangeFromKey(aE);
	aLEx.Append(aE);
      }
    }
    
    Standard_Boolean bFlag;
    bFlag=Standard_True;
    aNbMapEE=aMapEE.Extent();
    for (i=1; i<=aNbMapEE; i++) {
      const TopTools_ListOfShape& aLEx=aMapEE(i);
      aNbE=aLEx.Extent();
      if (aNbE==1) {
	// usual case
	continue;
      }
      else if (aNbE==2){
	const TopoDS_Shape& aE1=aLEx.First();
	const TopoDS_Shape& aE2=aLEx.Last();
	if (aE1.IsSame(aE2)) {
	  bFlag=Standard_False;
	  break;
	}
      }
      else {
	bFlag=Standard_False;
	break;
      }
    }
    myNothingToDo=myNothingToDo && bFlag;
  }
  // 
  //
  if (myNothingToDo) {
    myErrorStatus=0;
    return;
  }
  //
  // 3. Angles in mySmartMap
  BRepAdaptor_Surface aBAS(myFace);
  const GeomAdaptor_Surface& aGAS=aBAS.Surface();
  for (i=1; i<=aNb; i++) {
    const TopoDS_Vertex& aV=TopoDS::Vertex (mySmartMap.FindKey(i));
    const BOP_ListOfEdgeInfo& aLEInfo= mySmartMap(i);

    BOP_ListIteratorOfListOfEdgeInfo anIt(aLEInfo);
    for (; anIt.More(); anIt.Next()) {
      BOP_EdgeInfo& anEdgeInfo=anIt.Value();
      const TopoDS_Edge& aE=anEdgeInfo.Edge();
      //
      TopoDS_Vertex aVV=aV;
      //
      anIsIn=anEdgeInfo.IsIn();
      if (anIsIn) {
	//
	aVV.Orientation(TopAbs_REVERSED);
	anAngle=Angle2D (aVV, aE, myFace, aGAS, Standard_True);
      }
      // 
      else { // OUT
	//
	aVV.Orientation(TopAbs_FORWARD);
	anAngle=Angle2D (aVV, aE, myFace, aGAS, Standard_False);
      }
      anEdgeInfo.SetAngle(anAngle);
      
    }
  }
  //
  // 4. Do
  //
  Standard_Boolean anIsOut, anIsNotPassed;
  
  TopTools_SequenceOfShape aLS, aVertVa;
  TColgp_SequenceOfPnt2d aCoordVa;
  
  BOP_ListIteratorOfListOfEdgeInfo anIt;

  for (i=1; i<=aNb; i++) {
    const TopoDS_Vertex aVa=TopoDS::Vertex (mySmartMap.FindKey(i));
    const BOP_ListOfEdgeInfo& aLEInfo=mySmartMap(i);
    
    anIt.Initialize(aLEInfo);
    for (; anIt.More(); anIt.Next()) {
      BOP_EdgeInfo& anEdgeInfo=anIt.Value();
      const TopoDS_Edge& aEOuta=anEdgeInfo.Edge();
      
      anIsOut=!anEdgeInfo.IsIn();
      anIsNotPassed=!anEdgeInfo.Passed();
      
      if (anIsOut && anIsNotPassed) {
	//
	aLS.Clear();
	aVertVa.Clear();
	aCoordVa.Clear();
	//
	Path(aGAS, myFace, aVa, aEOuta, anEdgeInfo, aLS, 
	     aVertVa, aCoordVa, myShapes, mySmartMap);
      }
    }
  }
  //
  {
    Standard_Integer aNbV, aNbE;
    TopoDS_Vertex aV1, aV2;
    BOPTColStd_ListOfListOfShape aShapes;
    BOPTColStd_ListIteratorOfListOfListOfShape anItW(myShapes);
    
    for (; anItW.More(); anItW.Next()) {
      TopTools_IndexedMapOfShape aMV, aME;
      const TopTools_ListOfShape& aLE=anItW.Value();
      TopTools_ListIteratorOfListOfShape anItE(aLE);
      for (; anItE.More(); anItE.Next()) {
	const TopoDS_Edge& aE=TopoDS::Edge(anItE.Value());
	aME.Add(aE);
	TopExp::Vertices(aE, aV1, aV2);
	aMV.Add(aV1);
	aMV.Add(aV2);
      }
      aNbV=aMV.Extent();
      aNbE=aME.Extent();
      if (aNbV<=aNbE) {
	aShapes.Append(aLE);
      }
    }
    //
    myShapes.Clear();
    anItW.Initialize(aShapes);
    for (; anItW.More(); anItW.Next()) {
      const TopTools_ListOfShape& aLE=anItW.Value();
      myShapes.Append(aLE);
    }
  }
  //
  myErrorStatus=0;
}
Esempio n. 12
0
//=======================================================================
//function : Perform
//purpose  : 
//=======================================================================
void Partition_Loop::Perform()
{

  TopTools_DataMapOfShapeListOfShape MVE;
  TopTools_DataMapIteratorOfDataMapOfShapeListOfShape Mapit, Mapit1;  
  TopTools_ListIteratorOfListOfShape                  itl;
  TopoDS_Vertex                                       V1,V2;

  //-----------------------------------
  // Construction map vertex => edges
  //-----------------------------------
  for (itl.Initialize(myConstEdges); itl.More(); itl.Next()) {
    TopoDS_Edge& E = TopoDS::Edge(itl.Value());
    StoreInMVE(myFace,E,MVE);
  }

  //----------------------------------------------
  // Construction of all the wires and of all the new faces. 
  //----------------------------------------------
  TopTools_MapOfOrientedShape UsedEdges;

  while (!MVE.IsEmpty()) {
    TopoDS_Vertex    VF,CV;
    TopoDS_Edge      CE,NE,EF;
    TopoDS_Wire      NW;
    BRep_Builder     B;
    Standard_Boolean End= Standard_False;

    B.MakeWire(NW);
    //--------------------------------
    // EF first edge.
    //--------------------------------
    Mapit.Initialize(MVE);
    EF = CE = TopoDS::Edge(Mapit.Value().First());

    TopExp::Vertices(CE,V1,V2);
    //--------------------------------
    // VF first vertex 
    //--------------------------------
    if (CE.Orientation() == TopAbs_FORWARD) { 
      CV = VF = V1;
    }
    else  { 
      CV = VF = V2;
    }
    if (!MVE.IsBound(CV)) continue;
    for ( itl.Initialize(MVE(CV)); itl.More(); itl.Next()) {
      if (itl.Value().IsEqual(CE)) {
	MVE(CV).Remove(itl);
	break;
      }
    }

    int i = 0;
    while (!End) { 
      //-------------------------------
      // Construction of a wire.
      //-------------------------------
      TopExp::Vertices(CE,V1,V2);
      if (!CV.IsSame(V1)) CV = V1; else CV = V2; 
      B.Add (NW,CE);
      UsedEdges.Add(CE);

      //--------------
      // stop test
      //--------------			
      if (!MVE.IsBound(CV) || MVE(CV).IsEmpty() || CV.IsSame(VF) ) {
	if (CV.IsSame(VF)) {
	  if (MVE(CV).Extent() == 1 ) MVE.UnBind(CV);
	  else {
	    for ( itl.Initialize(MVE(CV)); itl.More(); itl.Next()) {
	      if (itl.Value().IsEqual(CE)) {
		MVE(CV).Remove(itl);
		break;
	      }
	    }
	  }
	}
	End=Standard_True;
      } 

      //--------------
      // select edge
      //--------------
      else {
	Standard_Boolean find = SelectEdge(myFace,CE,CV,NE,MVE(CV));
	if (find) {
	  CE=NE;
	  if (MVE(CV).IsEmpty()) MVE.UnBind(CV);
	  if (CE.IsNull() ) {
	    MESSAGE ( " CE is  NULL !!! " )
	    End=Standard_True;
	  }
	}
	else {
	  MESSAGE ( " edge doesn't exist " )
	  End=Standard_True;
	}
      }
    }

    //-----------------------------
    // Test if the wire is closed  
    //-----------------------------
    if (VF.IsSame(CV) && SamePnt2d(VF,EF,CE,myFace)) {
    }
    else{
      MESSAGE ( "wire not closed" )
    }
    myNewWires.Append (NW);			
  }

  PurgeNewEdges(myConstEdges,UsedEdges);

}
Esempio n. 13
0
//=======================================================================
//function : SelectEdge
//purpose  : Find the edge <NE> connected <CE> by the vertex <CV> in the list <LE>.
//           <NE> Is erased  of the list. If <CE> is too in the list <LE> 
//			 with the same orientation, it's erased of the list 
//=======================================================================
static Standard_Boolean  SelectEdge(const TopoDS_Face&    F,
				    const TopoDS_Edge&    CE,
				    const TopoDS_Vertex&  CV,
				    TopoDS_Edge&          NE,
				    TopTools_ListOfShape& LE)
{
  TopTools_ListIteratorOfListOfShape itl;
  NE.Nullify();
  for ( itl.Initialize(LE); itl.More(); itl.Next()) {
    if (itl.Value().IsEqual(CE)) {
      LE.Remove(itl);
      break;
    }
  }

  if (LE.Extent() > 1) {
    //--------------------------------------------------------------
    // Several possible edges.   
    // - Test the edges differents of CE 
    //--------------------------------------------------------------
    Standard_Real   cf, cl, f, l;
    TopoDS_Face FForward = F;
    Handle(Geom2d_Curve) Cc, C;
    FForward.Orientation(TopAbs_FORWARD);
			
    Cc = BRep_Tool::CurveOnSurface(CE,FForward,cf,cl);
    Standard_Real dist,distmin  = 100*BRep_Tool::Tolerance(CV);
    Standard_Real uc,u;
    if (CE.Orientation () == TopAbs_FORWARD) uc = cl;
    else                                     uc = cf;

    gp_Pnt2d P2,PV = Cc->Value(uc); 

    Standard_Real delta = FindDelta(LE,FForward);

    for ( itl.Initialize(LE); itl.More(); itl.Next()) {
      const TopoDS_Edge& E = TopoDS::Edge(itl.Value());
      if (!E.IsSame(CE)) {
	C = BRep_Tool::CurveOnSurface(E,FForward,f,l);
	if (E.Orientation () == TopAbs_FORWARD) u = f;
	else                                    u = l;
	P2 = C->Value(u);
	dist = PV.Distance(P2);
	if (dist <= distmin){
	  distmin = dist;
	}
				
      }
    }

    Standard_Real anglemax = - PI;
    TopoDS_Edge   SelectedEdge;	
    for ( itl.Initialize(LE); itl.More(); itl.Next()) {
      const TopoDS_Edge& E = TopoDS::Edge(itl.Value());
      if (!E.IsSame(CE)) {
	C = BRep_Tool::CurveOnSurface(E,FForward,f,l);
	if (E.Orientation () == TopAbs_FORWARD) u = f;
	else                                    u = l;
	P2 = C->Value(u);
	dist = PV.Distance(P2);
	if (dist <= distmin + (1./3)*delta){ 
	  gp_Pnt2d PC, P;
	  gp_Vec2d CTg1, CTg2, Tg1, Tg2;
	  Cc->D2(uc, PC, CTg1, CTg2);
	  C->D2(u, P, Tg1, Tg2);

	  Standard_Real angle;

	  if (CE.Orientation () == TopAbs_REVERSED && E.Orientation () == TopAbs_FORWARD) {
	    angle = CTg1.Angle(Tg1.Reversed());
	  }
	  else if (CE.Orientation () == TopAbs_FORWARD && E.Orientation () == TopAbs_REVERSED) {
	    angle = (CTg1.Reversed()).Angle(Tg1);
	  }
	  else if (CE.Orientation () == TopAbs_REVERSED && E.Orientation () == TopAbs_REVERSED) {
	    angle = CTg1.Angle(Tg1);
	  }
	  else if (CE.Orientation () == TopAbs_FORWARD && E.Orientation () == TopAbs_FORWARD) {
	    angle = (CTg1.Reversed()).Angle(Tg1.Reversed());
	  }
	  if (angle >= anglemax) {
	    anglemax = angle ;
	    SelectedEdge = E;	
	  }
	}
      }
    }
    for ( itl.Initialize(LE); itl.More(); itl.Next()) {
      const TopoDS_Edge& E = TopoDS::Edge(itl.Value());
      if (E.IsEqual(SelectedEdge)) {
	NE = TopoDS::Edge(E);
	LE.Remove(itl);
	break;
      }
    }					
  }
  else if (LE.Extent() == 1) {
    NE = TopoDS::Edge(LE.First());
    LE.RemoveFirst();
  }
  else {
    return Standard_False;
  }
  return Standard_True;
}
Esempio n. 14
0
//=======================================================================
//function : PerformLoops
//purpose  : 
//=======================================================================
  void GEOMAlgo_BuilderFace::PerformLoops()
{
  myErrorStatus=0;
  //
  Standard_Boolean bFlag;
  Standard_Integer aNbEA;
  TopTools_ListIteratorOfListOfShape aIt;
  TopTools_MapIteratorOfMapOfOrientedShape aItM;
  TopTools_IndexedDataMapOfShapeListOfShape aVEMap;
  TopTools_MapOfOrientedShape aMAdded;
  TopoDS_Iterator aItW;
  BRep_Builder aBB; 
  GEOMAlgo_WireEdgeSet aWES;
  GEOMAlgo_WESCorrector aWESCor;
  //
  // 1. Usual Wires 
  myLoops.Clear();
  aWES.SetFace(myFace);
  //
  aIt.Initialize (myShapes);
  for (; aIt.More(); aIt.Next()) {
    const TopoDS_Shape& aE=aIt.Value();
    if (!myShapesToAvoid.Contains(aE)) {
      aWES.AddStartElement(aE);
    }
  }
  //
  aWESCor.SetWES(aWES);
  aWESCor.Perform();
  //
  GEOMAlgo_WireEdgeSet& aWESN=aWESCor.NewWES();
  const TopTools_ListOfShape& aLW=aWESN.Shapes();
  //
  aIt.Initialize (aLW);
  for (; aIt.More(); aIt.Next()) {
    const TopoDS_Shape& aW=aIt.Value();
    myLoops.Append(aW);
  }
  //modified by NIZNHY-PKV Tue Aug  5 15:09:29 2008f
  // Post Treatment
  TopTools_MapOfOrientedShape aMEP;
  // 
  // a. collect all edges that are in loops
  aIt.Initialize (myLoops);
  for (; aIt.More(); aIt.Next()) {
    const TopoDS_Shape& aW=aIt.Value();
    aItW.Initialize(aW);
    for (; aItW.More(); aItW.Next()) {
      const TopoDS_Shape& aE=aItW.Value();
      aMEP.Add(aE);
    }
  }
  // 
  // b. collect all edges that are to avoid
  aItM.Initialize(myShapesToAvoid);
  for (; aItM.More(); aItM.Next()) {
    const TopoDS_Shape& aE=aItM.Key();
    aMEP.Add(aE);
  }
  //
  // c. add all edges that are not processed to myShapesToAvoid
  aIt.Initialize (myShapes);
  for (; aIt.More(); aIt.Next()) {
    const TopoDS_Shape& aE=aIt.Value();
    if (!aMEP.Contains(aE)) {
      myShapesToAvoid.Add(aE);
    }
  }
  //modified by NIZNHY-PKV Tue Aug  5 15:09:35 2008t
  //
  // 2. Internal Wires
  myLoopsInternal.Clear();
  //
  aNbEA=myShapesToAvoid.Extent();
  aItM.Initialize(myShapesToAvoid);
  for (; aItM.More(); aItM.Next()) {
    const TopoDS_Shape& aEE=aItM.Key();
    TopExp::MapShapesAndAncestors(aEE, TopAbs_VERTEX, TopAbs_EDGE, aVEMap);
  }
  //
  bFlag=Standard_True;
  aItM.Initialize(myShapesToAvoid);
  for (; aItM.More()&&bFlag; aItM.Next()) {
    const TopoDS_Shape& aEE=aItM.Key();
    if (!aMAdded.Add(aEE)) {
      continue;
    }
    //
    // make new wire
    TopoDS_Wire aW;
    aBB.MakeWire(aW);
    aBB.Add(aW, aEE);
    //
    aItW.Initialize(aW);
    for (; aItW.More()&&bFlag; aItW.Next()) {
      const TopoDS_Edge& aE=TopoDS::Edge(aItW.Value());
      //
      TopoDS_Iterator aItE(aE);
      for (; aItE.More()&&bFlag; aItE.Next()) {
	const TopoDS_Vertex& aV = TopoDS::Vertex(aItE.Value());
	const TopTools_ListOfShape& aLE=aVEMap.FindFromKey(aV);
	aIt.Initialize(aLE);
	for (; aIt.More()&&bFlag; aIt.Next()) { 
	  const TopoDS_Shape& aEx=aIt.Value();
	  if (aMAdded.Add(aEx)) {
	    aBB.Add(aW, aEx);
	    if(aMAdded.Extent()==aNbEA) {
	      bFlag=!bFlag;
	    }
	  }
	}//for (; aIt.More(); aIt.Next()) { 
      }//for (; aItE.More(); aItE.Next()) {
    }//for (; aItW.More(); aItW.Next()) {
    myLoopsInternal.Append(aW);
  }//for (; aItM.More(); aItM.Next()) {
}
Esempio n. 15
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();
  IntTools_Context& aCtx= pPF->ChangeContext();
  //
  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);
      bIsClosed=BRep_Tool::IsClosed(aE, aF);
      //
      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);
    /*
    {
      TopoDS_Compound aCx;
      BRep_Builder aBBx;
      TopTools_ListIteratorOfListOfShape aItx;
      //
      aBBx.MakeCompound(aCx);
      aBBx.Add(aCx, aFF);
      aItx.Initialize(aSE);
      for (; aItx.More(); aItx.Next()) {
	TopoDS_Shape& aEx=aItx.Value();
	aBBx.Add(aCx, aEx);
      }
      int a=0;
    }
    */
    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)
}
Esempio n. 16
0
//=======================================================================
//function : DetectShapes
//purpose  : 
//=======================================================================
void GEOMAlgo_GlueDetector::DetectShapes(const TopAbs_ShapeEnum aType)
{
  Standard_Boolean bDegenerated;
  Standard_Integer i, aNbF, aNbSDF, iErr;
  TopTools_IndexedMapOfShape aMF;
  TopTools_ListIteratorOfListOfShape aItLS;
  GEOMAlgo_PassKeyShape aPKF;
  GEOMAlgo_IndexedDataMapOfPassKeyShapeListOfShape aMPKLF;
  //
  myErrorStatus=0;
  //
  TopExp::MapShapes(myArgument, aType, aMF);
  //
  aNbF=aMF.Extent();
  for (i=1; i<=aNbF; ++i) {
    const TopoDS_Shape& aS=aMF(i);
    // 
    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, myTolerance, myContext);
    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
    }
    //
    if (aNbSDF==1) {
      continue;
    }
    //
    const TopoDS_Shape& aS1=aLSDF.First();  
    //
    if (aType==TopAbs_EDGE) {
      const TopoDS_Edge& aE1=*((TopoDS_Edge*)&aS1);
      bDegenerated=BRep_Tool::Degenerated(aE1);
      if (bDegenerated) {
	continue;
      }
    }
    //
    myImages.Bind(aS1, aLSDF);
    // origins
    aItLS.Initialize(aLSDF);
    for (; aItLS.More(); aItLS.Next()) {
      const TopoDS_Shape& aFSD=aItLS.Value();
      if (!myOrigins.IsBound(aFSD)) {
        myOrigins.Bind(aFSD, aS1);
      }
    }
  }// for (i=1; i<=aNbF; ++i)
}
//=======================================================================
//function : FillIn3DParts
//purpose  :
//=======================================================================
  void GEOMAlgo_Builder::FillIn3DParts()
{
  myErrorStatus=0;
  //
  const NMTDS_ShapesDataStructure& aDS=*myPaveFiller->DS();
  NMTTools_PaveFiller* pPF=myPaveFiller;
  const Handle(IntTools_Context)& aCtx= pPF->Context();
  //
  Standard_Boolean bIsIN, bHasImage;
  Standard_Integer aNbS, aNbSolids, i, j, aNbFaces, aNbFP, aNbFPx, aNbFIN, aNbLIF;
  TopAbs_ShapeEnum aType;
  TopAbs_State aState;
  TopTools_IndexedMapOfShape aMSolids, aMS, aMFaces, aMFIN;
  TopTools_MapOfShape aMFDone;
  TopTools_IndexedDataMapOfShapeListOfShape aMEF;
  TopTools_ListIteratorOfListOfShape aItS;
  TopoDS_Iterator aIt, aItF;
  BRep_Builder aBB;
  TopoDS_Solid aSolidSp;
  TopoDS_Face aFP;
  //
  myDraftSolids.Clear();
  //
  aNbS=aDS.NumberOfShapesOfTheObject();
  for (i=1; i<=aNbS; ++i) {
    const TopoDS_Shape& aS=aDS.Shape(i);
    //
    aType=aS.ShapeType();
    if (aType==TopAbs_SOLID) {
      // all solids from DS
      aMSolids.Add(aS);
    }
    else if (aType==TopAbs_FACE) {
      // all faces (originals from DS or theirs images)
      if (myImages.HasImage(aS)) {
        const TopTools_ListOfShape& aLS=myImages.Image(aS);
        aItS.Initialize(aLS);
        for (; aItS.More(); aItS.Next()) {
          const TopoDS_Shape& aFx=aItS.Value();
          //
          if (mySameDomainShapes.Contains(aFx)) {
            const TopoDS_Shape& aFSDx=mySameDomainShapes.FindFromKey(aFx);
            aMFaces.Add(aFSDx);
          }
          else {
            aMFaces.Add(aFx);
          }
        }
      }
      else {
        if (mySameDomainShapes.Contains(aS)) {
          const TopoDS_Shape& aFSDx=mySameDomainShapes.FindFromKey(aS);
          aMFaces.Add(aFSDx);
        }
        else {
          aMFaces.Add(aS);
        }
      }
    }
  }
  //
  aNbFaces=aMFaces.Extent();
  aNbSolids=aMSolids.Extent();
  //
  for (i=1; i<=aNbSolids; ++i) {
    const TopoDS_Solid& aSolid=TopoDS::Solid(aMSolids(i));
    aMFDone.Clear();
    aMFIN.Clear();
    aMEF.Clear();
    //
    aBB.MakeSolid(aSolidSp);
    //
    TopTools_ListOfShape aLIF;
    //
    BuildDraftSolid(aSolid, aSolidSp, aLIF);
    aNbLIF=aLIF.Extent();
    //
    // 1 all faces/edges from aSolid [ aMS ]
    bHasImage=Standard_False;
    aMS.Clear();
    aIt.Initialize(aSolid);
    for (; aIt.More(); aIt.Next()) {
      const TopoDS_Shape& aShell=aIt.Value();
      //
      if (myImages.HasImage(aShell)) {
        bHasImage=Standard_True;
        //
        const TopTools_ListOfShape& aLS=myImages.Image(aShell);
        aItS.Initialize(aLS);
        for (; aItS.More(); aItS.Next()) {
          const TopoDS_Shape& aSx=aItS.Value();
          aMS.Add(aSx);
          TopExp::MapShapes(aSx, TopAbs_FACE, aMS);
          TopExp::MapShapes(aSx, TopAbs_EDGE, aMS);
          TopExp::MapShapesAndAncestors(aSx, TopAbs_EDGE, TopAbs_FACE, aMEF);
        }
      }
      else {
        //aMS.Add(aShell);
        TopExp::MapShapes(aShell, TopAbs_FACE, aMS);
        //modified by NIZNHY-PKV Fri Dec 03 11:18:45 2010f
        TopExp::MapShapes(aShell, TopAbs_EDGE, aMS);
        //modified by NIZNHY-PKV Fri Dec 03 11:18:51 2010t
        TopExp::MapShapesAndAncestors(aShell, TopAbs_EDGE, TopAbs_FACE, aMEF);
      }
    }
    //
    // 2 all faces that are not from aSolid [ aLFP1 ]
    Standard_Integer aNbEFP;
    TopTools_IndexedDataMapOfShapeListOfShape aMEFP;
    TopTools_ListIteratorOfListOfShape aItFP, aItEx;
    TopTools_MapOfShape aMFence;
    TopTools_ListOfShape aLFP1, aLFP2, aLFP, aLCBF, aLFIN, aLEx;//*pLFP,
    //
    // for all non-solid faces build EF map [ aMEFP ]
    for (j=1; j<=aNbFaces; ++j) {
      const TopoDS_Shape& aFace=aMFaces(j);
      if (!aMS.Contains(aFace)) {
        TopExp::MapShapesAndAncestors(aFace, TopAbs_EDGE, TopAbs_FACE, aMEFP);
      }
    }
    //
    // among all faces from aMEFP select these that have same edges
    // with the solid (i.e aMEF). These faces will be treated first
    // to prevent the usage of 3D classifier.
    // The full list of faces to process is aLFP1.
    aNbEFP=aMEFP.Extent();
    for (j=1; j<=aNbEFP; ++j) {
      const TopoDS_Shape& aE=aMEFP.FindKey(j);
      //
      if (aMEF.Contains(aE)) { // !!
        const TopTools_ListOfShape& aLF=aMEFP(j);
        aItFP.Initialize(aLF);
        for (; aItFP.More(); aItFP.Next()) {
          const TopoDS_Shape& aF=aItFP.Value();
          if (aMFence.Add(aF)) {
            aLFP1.Append(aF);
          }
        }
      }
      else {
        aLEx.Append(aE);
      }
    }
    //
    aItEx.Initialize(aLEx);
    for (; aItEx.More(); aItEx.Next()) {
      const TopoDS_Shape& aE=aItEx.Value();
      const TopTools_ListOfShape& aLF=aMEFP.FindFromKey(aE);
      aItFP.Initialize(aLF);
      for (; aItFP.More(); aItFP.Next()) {
        const TopoDS_Shape& aF=aItFP.Value();
        if (aMFence.Add(aF)) {
          aLFP2.Append(aF);
        }
      }
    }
    aLFP1.Append(aLFP2);
    //==========
    //
    // 3 Process faces aLFP1
    aNbFP=aLFP1.Extent();
    aItFP.Initialize(aLFP1);
    for (; aItFP.More(); aItFP.Next()) {
      const TopoDS_Shape& aSP=aItFP.Value();
      if (!aMFDone.Add(aSP)) {
        continue;
      }

      //
      // first face to process
      aFP=TopoDS::Face(aSP);
      bIsIN= GEOMAlgo_Tools3D::IsInternalFace(aFP, aSolidSp, aMEF, 1.e-14, aCtx);
      aState=(bIsIN) ? TopAbs_IN : TopAbs_OUT;
      //
      // collect faces to process [ aFP is the first ]
      aLFP.Clear();
      aLFP.Append(aFP);
      aItS.Initialize(aLFP1);
      for (; aItS.More(); aItS.Next()) {
        const TopoDS_Shape& aSk=aItS.Value();
        if (!aMFDone.Contains(aSk)) {
          aLFP.Append(aSk);
        }
      }
      //
      // Connexity Block that spreads from aFP the Bound
      // or till the end of the block itself
      aLCBF.Clear();
      GEOMAlgo_Tools3D::MakeConnexityBlock(aLFP, aMS, aLCBF);
      //
      // fill states for the Connexity Block
      aItS.Initialize(aLCBF);
      for (; aItS.More(); aItS.Next()) {
        const TopoDS_Shape& aSx=aItS.Value();
        aMFDone.Add(aSx);
        if (aState==TopAbs_IN) {
          aMFIN.Add(aSx);
        }
      }
      //
      aNbFPx=aMFDone.Extent();
      if (aNbFPx==aNbFP) {
        break;
      }
    }//for (; aItFP.More(); aItFP.Next())
    //
    // faces Inside aSolid
    aLFIN.Clear();
    aNbFIN=aMFIN.Extent();
    if (aNbFIN || aNbLIF) {
      for (j=1; j<=aNbFIN; ++j) {
        const TopoDS_Shape& aFIN=aMFIN(j);
        aLFIN.Append(aFIN);
      }
      //
      aItS.Initialize(aLIF);
      for (; aItS.More(); aItS.Next()) {
        const TopoDS_Shape& aFIN=aItS.Value();
        aLFIN.Append(aFIN);
      }
      //
      myInParts.Add(aSolid, aLFIN);
    }
    if (aNbFIN || bHasImage) {
      myDraftSolids.Add(aSolid, aSolidSp);
    }
  }//for (i=1; i<=aNbSolids; ++i) { // next solid
}
Esempio n. 18
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");
    }
}