mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-26 10:19:45 +03:00
List of resolved warnings: c4063: Aspect.cdl; TObj_Application.cxx; PCDM.cdl; OpenGl_Workspace_5.cxx; c4100: XDEDRAW.cxx; ViewerTest_ViewerCommands.cxx; TopOpeBRep_FacesFiller_1.cxx; TopClass_Classifier3d.gxx; TDataStd_ReferenceArray.cxx; QABugs_19.cxx; IntPatch_ImpImpIntersection_5.gxx; HLRTopoBRep_DSFiller.cxx; HLRBRep_Data.lxx; DPrsStd_AISPresentationCommands.cxx; BRepMesh_Delaun.cxx; c4127: BOPTools_AlgoTools2D.cxx; MAT_Mat.gxx; GeomFill_SweepSectionGenerator.cxx; BRepMesh_Delaun.cxx; c4189: IntCurveSurface_Inter.gxx; IGESToBRep_BRepEntity.cxx; BRepMesh_Delaun.cxx; BRepAlgo_Loop.cxx; IntStart_SearchOnBoundaries_1.gxx; c4190: Plugin_Macro.hxx; c4389: Visual3d_View.cxx; TopOpeBRep/TopOpeBRep_vpr.cxx; TDataStd_BooleanArray.cxx; IntPatch_ALine.cxx; c4701: BRepAlgo.cxx; c4702: MNaming_NamingRetrievalDriver_1.cxx; MNaming_NamingRetrievalDriver_2.cxx; BRepClass3d_SolidExplorer.cxx; c4706: TestTopOpe_BOOP.cxx; Additional fixes: - old-style declarations of C functions in IGES and STEP parsers - clean-up of debug code, fixes for building in Debug mode - in BRepFill_TrimShellCorner.cxx, lines 878-9, wrong use of assignment instead of comparison fixed - fix for Plugin_Macro reverted; warning 4190 disabled instead - in IntPatch_ALine.cxx, line 520, wrong comparison of boolean with index fixed - in InterfaceGraphic_Visual3d.hxx, field IsCustomMatrix made boolean - in TopOpeBRepBuild_ShapeSet, obsolete (unused) methods removed
1299 lines
38 KiB
C++
Executable File
1299 lines
38 KiB
C++
Executable File
// Created on: 1993-05-07
|
|
// Created by: Jean Yves LEBEY
|
|
// Copyright (c) 1993-1999 Matra Datavision
|
|
// Copyright (c) 1999-2012 OPEN CASCADE SAS
|
|
//
|
|
// The content of this file is subject to the Open CASCADE Technology Public
|
|
// License Version 6.5 (the "License"). You may not use the content of this file
|
|
// except in compliance with the License. Please obtain a copy of the License
|
|
// at http://www.opencascade.org and read it completely before using this file.
|
|
//
|
|
// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
|
|
// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
|
|
//
|
|
// The Original Code and all software distributed under the License is
|
|
// distributed on an "AS IS" basis, without warranty of any kind, and the
|
|
// Initial Developer hereby disclaims all such warranties, including without
|
|
// limitation, any warranties of merchantability, fitness for a particular
|
|
// purpose or non-infringement. Please see the License for the specific terms
|
|
// and conditions governing the rights and limitations under the License.
|
|
|
|
|
|
#include <TopOpeBRep_ShapeIntersector.ixx>
|
|
|
|
#include <TopAbs.hxx>
|
|
#include <Bnd_Box.hxx>
|
|
#include <TopOpeBRepTool_box.hxx>
|
|
#include <TopOpeBRep_define.hxx>
|
|
|
|
#ifdef DEB
|
|
extern Standard_Boolean TopOpeBRep_GettraceSI();
|
|
extern Standard_Boolean TopOpeBRep_GetcontextFFOR();
|
|
extern Standard_Integer SAVFFi1; // FacesIntersector
|
|
extern Standard_Integer SAVFFi2; // FacesIntersector
|
|
extern void TopOpeBRep_SettraceEEFF(const Standard_Boolean b);
|
|
extern Standard_Boolean TopOpeBRep_GettraceEEFF(const Standard_Integer e1,const Standard_Integer e2,const Standard_Integer f1,const Standard_Integer f2);
|
|
void seteeff(const Standard_Boolean b,const Standard_Integer e1,const Standard_Integer e2, const Standard_Integer f1,const Standard_Integer f2)
|
|
{cout<<"b,e1,e2,f1,f2 : "<<b<<" "<<e1<<","<<e2<<","<<f1<<","<<f2<<endl;TopOpeBRep_SettraceEEFF(b);}
|
|
void seteefft(const Standard_Integer e1,const Standard_Integer e2, const Standard_Integer f1,const Standard_Integer f2) {seteeff(Standard_True,e1,e2,f1,f2);}
|
|
void seteefff(const Standard_Integer e1,const Standard_Integer e2, const Standard_Integer f1,const Standard_Integer f2) {seteeff(Standard_False,e1,e2,f1,f2);}
|
|
#endif
|
|
|
|
// modified by NIZHNY-OFV Thu Apr 18 17:15:38 2002 (S)
|
|
#include <TopoDS.hxx>
|
|
#include <TopoDS_Shape.hxx>
|
|
#include <TopoDS_Solid.hxx>
|
|
#include <TopoDS_Shell.hxx>
|
|
#include <TopoDS_Face.hxx>
|
|
#include <TopoDS_Wire.hxx>
|
|
#include <TopoDS_Edge.hxx>
|
|
#include <TopExp_Explorer.hxx>
|
|
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
|
|
#include <TopTools_ListOfShape.hxx>
|
|
#include <TopExp.hxx>
|
|
#include <gp_Pnt.hxx>
|
|
#include <gp_Vec.hxx>
|
|
#include <BRepLib_MakeEdge.hxx>
|
|
#include <BRepLib_MakeWire.hxx>
|
|
#include <BRepLib_MakeFace.hxx>
|
|
#include <BRep_Builder.hxx>
|
|
#include <BRepAdaptor_Surface.hxx>
|
|
static Standard_Integer OneShapeIsHalfSpace(const TopoDS_Shape& S1,const TopoDS_Shape& S2);
|
|
static TopoDS_Solid GetNewSolid(const TopoDS_Shape& S, TopoDS_Face& F);
|
|
// modified by NIZHNY-OFV Thu Apr 18 17:16:45 2002 (F)
|
|
|
|
//=======================================================================
|
|
//function : TopOpeBRep_ShapeIntersector
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
TopOpeBRep_ShapeIntersector::TopOpeBRep_ShapeIntersector()
|
|
{
|
|
Reset();
|
|
myFFIntersector.GetTolerances(myTol1,myTol2);
|
|
myHBoxTool = FBOX_GetHBoxTool();
|
|
myFaceScanner.ChangeBoxSort().SetHBoxTool(myHBoxTool);
|
|
myEdgeScanner.ChangeBoxSort().SetHBoxTool(myHBoxTool);
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Reset
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void TopOpeBRep_ShapeIntersector::Reset()
|
|
{
|
|
myIntersectionDone = Standard_False;
|
|
|
|
myFFDone = Standard_False;
|
|
myFFSameDomain = Standard_False;
|
|
myEEFFDone = Standard_False;
|
|
myEFDone = Standard_False;
|
|
myFEDone = Standard_False;
|
|
myEEDone = Standard_False;
|
|
|
|
myFFInit = Standard_False;
|
|
myEEFFInit = Standard_False;
|
|
myEFInit = Standard_False;
|
|
myFEInit = Standard_False;
|
|
myEEInit = Standard_False;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Init
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void TopOpeBRep_ShapeIntersector::Init
|
|
(const TopoDS_Shape& S1, const TopoDS_Shape& S2)
|
|
{
|
|
Reset();
|
|
myShape1 = S1;
|
|
myShape2 = S2;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : SetIntersectionDone
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void TopOpeBRep_ShapeIntersector::SetIntersectionDone()
|
|
{
|
|
myIntersectionDone = (myFFDone ||
|
|
myEEFFDone ||
|
|
myFEDone ||
|
|
myEFDone ||
|
|
myEEDone);
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : CurrentGeomShape
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
const TopoDS_Shape& TopOpeBRep_ShapeIntersector::CurrentGeomShape
|
|
(const Standard_Integer Index) const
|
|
{
|
|
if ( myIntersectionDone ) {
|
|
if (myFFDone) {
|
|
if ( Index == 1 ) return myFaceScanner.Current();
|
|
else if ( Index == 2 ) return myFaceExplorer.Current();
|
|
}
|
|
else if (myEEFFDone) {
|
|
if ( Index == 1 ) return myEdgeScanner.Current();
|
|
else if ( Index == 2 ) return myEdgeExplorer.Current();
|
|
}
|
|
else if (myFEDone) {
|
|
if ( Index == 1 ) return myFaceScanner.Current();
|
|
else if ( Index == 2 ) return myEdgeExplorer.Current();
|
|
}
|
|
else if (myEFDone) {
|
|
if ( Index == 1 ) return myEdgeScanner.Current();
|
|
else if ( Index == 2 ) return myFaceExplorer.Current();
|
|
}
|
|
else if (myEEDone) {
|
|
if ( Index == 1 ) return myEdgeScanner.Current();
|
|
else if ( Index == 2 ) return myEdgeExplorer.Current();
|
|
}
|
|
}
|
|
|
|
Standard_Failure::Raise("CurrentGeomShape : no intersection");
|
|
TopoDS_Shape* bid = new TopoDS_Shape();
|
|
return *bid;
|
|
}
|
|
//modified by NIZNHY-PKV Fri Sep 24 11:02:59 1999 from
|
|
//=======================================================================
|
|
//function : RejectedFaces
|
|
//purpose :
|
|
//=======================================================================
|
|
void TopOpeBRep_ShapeIntersector::RejectedFaces (const TopoDS_Shape& anObj,
|
|
const TopoDS_Shape& aReference,
|
|
TopTools_ListOfShape& aListOfShape)
|
|
{
|
|
|
|
Standard_Integer isHalfSpace = OneShapeIsHalfSpace( anObj, aReference );
|
|
if( isHalfSpace != 0 )
|
|
{
|
|
TopoDS_Face newRejectFace;
|
|
TopoDS_Solid newSolid;
|
|
aListOfShape.Clear();
|
|
|
|
if( isHalfSpace == 1 )
|
|
{
|
|
newSolid = GetNewSolid( anObj, newRejectFace );
|
|
Init( newSolid, aReference );
|
|
|
|
TopAbs_ShapeEnum tscann = TopAbs_SOLID;
|
|
TopAbs_ShapeEnum texplo = TopAbs_FACE;
|
|
myFaceScanner.Clear();
|
|
myFaceScanner.AddBoxesMakeCOB( aReference, tscann );
|
|
myFaceExplorer.Init( newSolid, texplo );
|
|
|
|
for(; myFaceExplorer.More(); myFaceExplorer.Next())
|
|
{
|
|
TopOpeBRepTool_BoxSort& aBS = myFaceScanner.ChangeBoxSort();
|
|
if(!aBS.Compare(myFaceExplorer.Current()).More())
|
|
{
|
|
const TopoDS_Shape& aS=myFaceExplorer.Current();
|
|
aListOfShape.Append (aS);
|
|
}
|
|
}
|
|
|
|
texplo = TopAbs_EDGE;
|
|
myFaceScanner.Clear();
|
|
myFaceScanner.AddBoxesMakeCOB( aReference, tscann );
|
|
myFaceExplorer.Init( newSolid, texplo );
|
|
|
|
for(; myFaceExplorer.More(); myFaceExplorer.Next())
|
|
{
|
|
TopOpeBRepTool_BoxSort& aBS = myFaceScanner.ChangeBoxSort();
|
|
if(!aBS.Compare(myFaceExplorer.Current()).More())
|
|
{
|
|
const TopoDS_Shape& aS=myFaceExplorer.Current();
|
|
aListOfShape.Append (aS);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
newSolid = GetNewSolid( aReference, newRejectFace );
|
|
Init( anObj, newSolid );
|
|
|
|
TopAbs_ShapeEnum tscann = TopAbs_SOLID;
|
|
TopAbs_ShapeEnum texplo = TopAbs_FACE;
|
|
myFaceScanner.Clear();
|
|
myFaceScanner.AddBoxesMakeCOB( newSolid, tscann );
|
|
myFaceExplorer.Init( anObj, texplo);
|
|
|
|
for(; myFaceExplorer.More(); myFaceExplorer.Next())
|
|
{
|
|
TopOpeBRepTool_BoxSort& aBS = myFaceScanner.ChangeBoxSort();
|
|
if(!aBS.Compare(myFaceExplorer.Current()).More())
|
|
{
|
|
const TopoDS_Shape& aS=myFaceExplorer.Current();
|
|
aListOfShape.Append (aS);
|
|
}
|
|
}
|
|
|
|
texplo = TopAbs_EDGE;
|
|
myFaceScanner.Clear();
|
|
myFaceScanner.AddBoxesMakeCOB( newSolid, tscann );
|
|
myFaceExplorer.Init( anObj, texplo );
|
|
|
|
for(; myFaceExplorer.More(); myFaceExplorer.Next())
|
|
{
|
|
TopOpeBRepTool_BoxSort& aBS = myFaceScanner.ChangeBoxSort();
|
|
if(!aBS.Compare(myFaceExplorer.Current()).More())
|
|
{
|
|
const TopoDS_Shape& aS=myFaceExplorer.Current();
|
|
aListOfShape.Append (aS);
|
|
}
|
|
}
|
|
}
|
|
// remove all shapes of < newRejectFace > from list
|
|
TopExp_Explorer ExpRF(newRejectFace, TopAbs_EDGE);
|
|
for(; ExpRF.More(); ExpRF.Next() )
|
|
{
|
|
const TopoDS_Edge& edgef = TopoDS::Edge( ExpRF.Current() );
|
|
TopTools_ListIteratorOfListOfShape it( aListOfShape );
|
|
for(; it.More(); it.Next() )
|
|
{
|
|
const TopoDS_Shape& shape = it.Value();
|
|
|
|
if( shape.ShapeType() != TopAbs_EDGE )
|
|
continue;
|
|
|
|
const TopoDS_Edge& edgel = TopoDS::Edge( shape );
|
|
if( edgef.IsSame( edgel ) )
|
|
{
|
|
aListOfShape.Remove(it);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
TopTools_ListIteratorOfListOfShape it( aListOfShape );
|
|
for(; it.More(); it.Next() )
|
|
{
|
|
const TopoDS_Shape& shape = it.Value();
|
|
|
|
if( shape.ShapeType() != TopAbs_FACE )
|
|
continue;
|
|
|
|
const TopoDS_Face& facel = TopoDS::Face( shape );
|
|
if( facel.IsSame( newRejectFace ) )
|
|
{
|
|
aListOfShape.Remove(it);
|
|
break;
|
|
}
|
|
}
|
|
|
|
Init(anObj, aReference);
|
|
return;
|
|
}
|
|
|
|
Init(anObj, aReference);
|
|
|
|
aListOfShape.Clear();
|
|
//find faces to reject
|
|
|
|
TopAbs_ShapeEnum tscann = TopAbs_SOLID;
|
|
TopAbs_ShapeEnum texplo = TopAbs_FACE;
|
|
myFaceScanner.Clear();
|
|
myFaceScanner.AddBoxesMakeCOB(aReference,tscann);
|
|
myFaceExplorer.Init(anObj,texplo);
|
|
|
|
for(; myFaceExplorer.More(); myFaceExplorer.Next()) {
|
|
TopOpeBRepTool_BoxSort& aBS = myFaceScanner.ChangeBoxSort();
|
|
if(!aBS.Compare(myFaceExplorer.Current()).More()) {
|
|
const TopoDS_Shape& aS=myFaceExplorer.Current();
|
|
aListOfShape.Append (aS);
|
|
}
|
|
}
|
|
|
|
//modified by NIZHNY-MZV Wed Apr 5 09:45:17 2000
|
|
texplo = TopAbs_EDGE;
|
|
myFaceScanner.Clear();
|
|
myFaceScanner.AddBoxesMakeCOB(aReference,tscann);
|
|
myFaceExplorer.Init(anObj,texplo);
|
|
|
|
for(; myFaceExplorer.More(); myFaceExplorer.Next()) {
|
|
TopOpeBRepTool_BoxSort& aBS = myFaceScanner.ChangeBoxSort();
|
|
if(!aBS.Compare(myFaceExplorer.Current()).More()) {
|
|
const TopoDS_Shape& aS=myFaceExplorer.Current();
|
|
aListOfShape.Append (aS);
|
|
}
|
|
}
|
|
|
|
//modified by NIZHNY-MZV Wed Apr 5 09:45:17 2000
|
|
/* texplo = TopAbs_VERTEX;
|
|
myFaceScanner.Clear();
|
|
myFaceScanner.AddBoxesMakeCOB(aReference,tscann);
|
|
myFaceExplorer.Init(anObj,texplo);
|
|
|
|
for(; myFaceExplorer.More(); myFaceExplorer.Next()) {
|
|
TopOpeBRepTool_BoxSort& aBS = myFaceScanner.ChangeBoxSort();
|
|
if(!aBS.Compare(myFaceExplorer.Current()).More()) {
|
|
const TopoDS_Shape& aS=myFaceExplorer.Current();
|
|
aListOfShape.Append (aS);
|
|
}
|
|
}
|
|
*/
|
|
}
|
|
//modified by NIZNHY-PKV Fri Sep 24 11:03:02 1999 to
|
|
|
|
|
|
|
|
|
|
//=======================================================================
|
|
//function : InitIntersection
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void TopOpeBRep_ShapeIntersector::InitIntersection (const TopoDS_Shape& S1, const TopoDS_Shape& S2)
|
|
{
|
|
Init(S1,S2);
|
|
|
|
InitFFIntersection();
|
|
if ( MoreFFCouple() ) return;
|
|
|
|
InitFEIntersection();
|
|
if ( MoreFECouple() ) return;
|
|
|
|
InitEFIntersection();
|
|
if ( MoreEFCouple() ) return;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : InitIntersection
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void TopOpeBRep_ShapeIntersector::InitIntersection
|
|
(const TopoDS_Shape& S1, const TopoDS_Shape& S2,
|
|
const TopoDS_Face& F1, const TopoDS_Face& F2)
|
|
{
|
|
Init(S1,S2);
|
|
|
|
myEEFace1 = F1;
|
|
myEEFace2 = F2;
|
|
|
|
InitEEIntersection();
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : MoreIntersection
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Boolean TopOpeBRep_ShapeIntersector::MoreIntersection() const
|
|
{
|
|
Standard_Boolean res = myIntersectionDone;
|
|
|
|
#ifdef DEB
|
|
if (TopOpeBRep_GettraceSI() && res) {
|
|
if ( myFFDone ) cout<<"FF : ";
|
|
else if ( myEEFFDone ) cout<<" EE : ";
|
|
DumpCurrent(1);
|
|
DumpCurrent(2);
|
|
if ( myFFDone && myFFSameDomain ) cout<<"(FF SameDomain)";
|
|
else if ( myEEFFDone ) cout<<"(EE of FF SameDomain)";
|
|
else if ( myEEDone ) cout<<"EE : ";
|
|
cout<<endl;
|
|
if (myEEFFDone) {
|
|
Standard_Integer ie1 = myEdgeScanner.Index();
|
|
Standard_Integer ie2 = myEdgeExplorer.Index();
|
|
Standard_Integer if1 = myFaceScanner.Index();
|
|
Standard_Integer if2 = myFaceExplorer.Index();
|
|
cout<<" trc teeff 1 "<<ie1<<" "<<ie2<<" "<<if1<<" "<<if2<<"; # ie1 ie2 if1 if2"<<endl;
|
|
Standard_Boolean b = TopOpeBRep_GettraceEEFF(ie1,ie2,if1,if2);
|
|
if (b) seteefft(ie1,ie2,if1,if2);
|
|
else seteefff(ie1,ie2,if1,if2);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
return res;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : DumpCurrent
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
#ifdef DEB
|
|
void TopOpeBRep_ShapeIntersector::DumpCurrent(const Standard_Integer K) const
|
|
{
|
|
if ( myFFDone ) {
|
|
if ( K == 1 ) myFaceScanner.DumpCurrent(cout);
|
|
else if ( K == 2 ) myFaceExplorer.DumpCurrent(cout);
|
|
}
|
|
else if ( myEEFFDone ) {
|
|
if ( K == 1 ) myEdgeScanner.DumpCurrent(cout);
|
|
else if ( K == 2 ) myEdgeExplorer.DumpCurrent(cout);
|
|
}
|
|
else if ( myFEDone ) {
|
|
if ( K == 1 ) myFaceScanner.DumpCurrent(cout);
|
|
else if ( K == 2 ) myEdgeExplorer.DumpCurrent(cout);
|
|
}
|
|
else if ( myEFDone ) {
|
|
if ( K == 1 ) myEdgeScanner.DumpCurrent(cout);
|
|
else if ( K == 2 ) myFaceExplorer.DumpCurrent(cout);
|
|
}
|
|
else if ( myEEDone ) {
|
|
if ( K == 1 ) myEdgeScanner.DumpCurrent(cout);
|
|
else if ( K == 2 ) myEdgeExplorer.DumpCurrent(cout);
|
|
}
|
|
}
|
|
#else
|
|
void TopOpeBRep_ShapeIntersector::DumpCurrent(const Standard_Integer) const {}
|
|
#endif
|
|
|
|
//=======================================================================
|
|
//function : Index
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
#ifdef DEB
|
|
Standard_Integer TopOpeBRep_ShapeIntersector::Index
|
|
(const Standard_Integer K)const
|
|
{
|
|
Standard_Integer i = 0;
|
|
|
|
if ( myFFDone ) {
|
|
if ( K == 1 ) i = myFaceScanner.Index();
|
|
else if ( K == 2 ) i = myFaceExplorer.Index();
|
|
}
|
|
else if ( myEEFFDone ) {
|
|
if ( K == 1 ) i = myEdgeScanner.Index();
|
|
else if ( K == 2 ) i = myEdgeExplorer.Index();
|
|
}
|
|
else if ( myFEDone ) {
|
|
if ( K == 1 ) i = myFaceScanner.Index();
|
|
else if ( K == 2 ) i = myEdgeExplorer.Index();
|
|
}
|
|
else if ( myEFDone ) {
|
|
if ( K == 1 ) i = myEdgeScanner.Index();
|
|
else if ( K == 2 ) i = myFaceExplorer.Index();
|
|
}
|
|
else if ( myEEDone ) {
|
|
if ( K == 1 ) i = myEdgeScanner.Index();
|
|
else if ( K == 2 ) i = myEdgeExplorer.Index();
|
|
}
|
|
return i;
|
|
}
|
|
#else
|
|
Standard_Integer TopOpeBRep_ShapeIntersector::Index (const Standard_Integer)const
|
|
{
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
|
|
//=======================================================================
|
|
//function : NextIntersection
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void TopOpeBRep_ShapeIntersector::NextIntersection()
|
|
{
|
|
myIntersectionDone = Standard_False;
|
|
|
|
if (myFFSameDomain) {
|
|
// precedant etat du More() : 2 faces samedomain
|
|
myFFDone = Standard_False;
|
|
myFFSameDomain = Standard_False;
|
|
InitEEFFIntersection();
|
|
FindEEFFIntersection();
|
|
if ( !myIntersectionDone ) {
|
|
NextFFCouple();
|
|
FindFFIntersection();
|
|
}
|
|
}
|
|
else if (myFFDone) {
|
|
NextFFCouple();
|
|
FindFFIntersection();
|
|
}
|
|
else if ( myEEFFDone ) {
|
|
NextEEFFCouple();
|
|
FindEEFFIntersection();
|
|
if ( !myIntersectionDone ) {
|
|
NextFFCouple();
|
|
FindFFIntersection();
|
|
}
|
|
}
|
|
else if ( myFEDone ) {
|
|
NextFECouple();
|
|
FindFEIntersection();
|
|
}
|
|
else if ( myEFDone ) {
|
|
NextEFCouple();
|
|
FindEFIntersection();
|
|
}
|
|
else if ( myEEDone ) {
|
|
NextEECouple();
|
|
FindEEIntersection();
|
|
}
|
|
|
|
if ( !myIntersectionDone ) {
|
|
InitFFIntersection();
|
|
}
|
|
|
|
if ( !myIntersectionDone ) {
|
|
InitFEIntersection();
|
|
}
|
|
|
|
if ( !myIntersectionDone ) {
|
|
InitEFIntersection();
|
|
}
|
|
|
|
if ( !myIntersectionDone ) {
|
|
if ( !myEEFace1.IsNull() && !myEEFace2.IsNull() ) {
|
|
InitEEIntersection();
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
// ========
|
|
// FFFFFFFF
|
|
// ========
|
|
|
|
|
|
//=======================================================================
|
|
//function : InitFFIntersection
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void TopOpeBRep_ShapeIntersector::InitFFIntersection()
|
|
{
|
|
if ( !myFFInit) {
|
|
TopAbs_ShapeEnum tscann = TopAbs_FACE;
|
|
TopAbs_ShapeEnum texplo = TopAbs_FACE;
|
|
myFaceScanner.Clear();
|
|
myFaceScanner.AddBoxesMakeCOB(myShape1,tscann);
|
|
myFaceExplorer.Init(myShape2,texplo);
|
|
myFaceScanner.Init(myFaceExplorer);
|
|
FindFFIntersection();
|
|
}
|
|
myFFInit = Standard_True;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : FindFFIntersection
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void TopOpeBRep_ShapeIntersector::FindFFIntersection()
|
|
{
|
|
myFFDone = Standard_False;
|
|
myFFSameDomain = Standard_False ;
|
|
|
|
while ( MoreFFCouple() ) {
|
|
|
|
// The two candidate intersecting GeomShapes GS1,GS2 and their types t1,t2
|
|
const TopoDS_Shape& GS1 = myFaceScanner.Current();
|
|
const TopoDS_Shape& GS2 = myFaceExplorer.Current();
|
|
|
|
#ifdef DEB
|
|
SAVFFi1 = myFaceScanner.Index(); SAVFFi2 = myFaceExplorer.Index();
|
|
if (TopOpeBRep_GettraceSI()) {
|
|
cout<<"?? FF : ";
|
|
myFaceScanner.DumpCurrent(cout); myFaceExplorer.DumpCurrent(cout);
|
|
cout<<endl;
|
|
}
|
|
#endif
|
|
|
|
const TopOpeBRepTool_BoxSort& BS = myFaceScanner.BoxSort();
|
|
const Bnd_Box& B1 = BS.Box(GS1);
|
|
const Bnd_Box& B2 = BS.Box(GS2);
|
|
myFFIntersector.Perform(GS1,GS2,B1,B2);
|
|
Standard_Boolean ok = myFFIntersector.IsDone(); //xpu210998
|
|
if (!ok) {
|
|
NextFFCouple();
|
|
continue;
|
|
}
|
|
|
|
myFFSameDomain = myFFIntersector.SameDomain();
|
|
|
|
if (myFFSameDomain) {
|
|
myFFDone = Standard_True;
|
|
break;
|
|
}
|
|
else {
|
|
myFFDone = ! (myFFIntersector.IsEmpty());
|
|
|
|
// update face/face intersection tolerances
|
|
if (myFFDone) {
|
|
Standard_Real tol1,tol2;
|
|
myFFIntersector.GetTolerances(tol1,tol2);
|
|
myTol1 = Max(myTol1,tol1); myTol2 = Max(myTol2,tol2);
|
|
}
|
|
|
|
if ( myFFDone ) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
NextFFCouple();
|
|
}
|
|
|
|
SetIntersectionDone();
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : MoreFFCouple
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Boolean TopOpeBRep_ShapeIntersector::MoreFFCouple() const
|
|
{
|
|
Standard_Boolean more1 = myFaceScanner.More();
|
|
Standard_Boolean more2 = myFaceExplorer.More();
|
|
return (more1 && more2);
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : NextFFCouple
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void TopOpeBRep_ShapeIntersector::NextFFCouple()
|
|
{
|
|
myFaceScanner.Next();
|
|
Standard_Boolean b1,b2;
|
|
|
|
b1 = (!myFaceScanner.More());
|
|
b2 = (myFaceExplorer.More());
|
|
while ( b1 && b2 ) {
|
|
myFaceExplorer.Next();
|
|
myFaceScanner.Init(myFaceExplorer);
|
|
b1 = (!myFaceScanner.More());
|
|
b2 = (myFaceExplorer.More());
|
|
}
|
|
|
|
}
|
|
|
|
|
|
// ========
|
|
// EEFFEEFF
|
|
// ========
|
|
|
|
|
|
//=======================================================================
|
|
//function : InitEEFFIntersection
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void TopOpeBRep_ShapeIntersector::InitEEFFIntersection()
|
|
{
|
|
// prepare exploration of the edges of the two current SameDomain faces
|
|
TopoDS_Shape face1 = myFaceScanner.Current(); // -26-08-96
|
|
TopoDS_Shape face2 = myFaceExplorer.Current(); // -26-08-96
|
|
|
|
#ifdef DEB
|
|
if (TopOpeBRep_GetcontextFFOR()) {
|
|
face1.Orientation(TopAbs_FORWARD); //-05/07
|
|
face2.Orientation(TopAbs_FORWARD); //-05/07
|
|
cout<<"ctx : InitEEFFIntersection : faces FORWARD"<<endl;
|
|
}
|
|
#endif
|
|
|
|
const TopOpeBRepTool_BoxSort& BS = myFaceScanner.BoxSort();
|
|
const Bnd_Box& B1 = BS.Box(face1);
|
|
const Bnd_Box& B2 = BS.Box(face2);
|
|
myEEIntersector.SetFaces(face1,face2,B1,B2);
|
|
|
|
TopAbs_ShapeEnum tscann = TopAbs_EDGE;
|
|
TopAbs_ShapeEnum texplo = TopAbs_EDGE;
|
|
myEdgeScanner.Clear();
|
|
myEdgeScanner.AddBoxesMakeCOB(face1,tscann);
|
|
myEdgeExplorer.Init(face2,texplo);
|
|
myEdgeScanner.Init(myEdgeExplorer);
|
|
|
|
myEEFFInit = Standard_True;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : FindEEFFIntersection
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void TopOpeBRep_ShapeIntersector::FindEEFFIntersection()
|
|
{
|
|
myEEFFDone = Standard_False;
|
|
while ( MoreEEFFCouple() ) {
|
|
const TopoDS_Shape& GS1 = myEdgeScanner.Current();
|
|
const TopoDS_Shape& GS2 = myEdgeExplorer.Current();
|
|
myEEIntersector.Perform(GS1,GS2);
|
|
|
|
#ifdef DEB
|
|
if (TopOpeBRep_GettraceSI() && myEEIntersector.IsEmpty()) {
|
|
cout<<" EE : ";
|
|
myEdgeScanner.DumpCurrent(cout);
|
|
myEdgeExplorer.DumpCurrent(cout);
|
|
cout<<"(EE of FF SameDomain)";
|
|
cout<<" : EMPTY INTERSECTION";
|
|
cout<<endl;
|
|
}
|
|
#endif
|
|
|
|
myEEFFDone = ! (myEEIntersector.IsEmpty());
|
|
if (myEEFFDone) break;
|
|
else NextEEFFCouple();
|
|
}
|
|
SetIntersectionDone();
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : MoreEEFFCouple
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Boolean TopOpeBRep_ShapeIntersector::MoreEEFFCouple() const
|
|
{
|
|
Standard_Boolean more1 = myEdgeScanner.More();
|
|
Standard_Boolean more2 = myEdgeExplorer.More();
|
|
return (more1 && more2);
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : NextEEFFCouple
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void TopOpeBRep_ShapeIntersector::NextEEFFCouple()
|
|
{
|
|
myEdgeScanner.Next();
|
|
while ( ! myEdgeScanner.More() && myEdgeExplorer.More() ) {
|
|
myEdgeExplorer.Next();
|
|
myEdgeScanner.Init(myEdgeExplorer);
|
|
}
|
|
}
|
|
|
|
|
|
// ========
|
|
// FEFEFEFE
|
|
// ========
|
|
|
|
|
|
//=======================================================================
|
|
//function : InitFEIntersection
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void TopOpeBRep_ShapeIntersector::InitFEIntersection()
|
|
{
|
|
if ( !myFEInit) {
|
|
TopAbs_ShapeEnum tscann = TopAbs_FACE;
|
|
TopAbs_ShapeEnum texplo = TopAbs_EDGE;
|
|
myFaceScanner.Clear();
|
|
myFaceScanner.AddBoxesMakeCOB(myShape1,tscann);
|
|
myEdgeExplorer.Init(myShape2,texplo,TopAbs_FACE); // NYI defaut de spec
|
|
myFaceScanner.Init(myEdgeExplorer);
|
|
FindFEIntersection();
|
|
}
|
|
myFEInit = Standard_True;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : FindFEIntersection
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void TopOpeBRep_ShapeIntersector::FindFEIntersection()
|
|
{
|
|
myFEDone = Standard_False;
|
|
while ( MoreFECouple() ) {
|
|
const TopoDS_Shape& GS1 = myFaceScanner.Current();
|
|
const TopoDS_Shape& GS2 = myEdgeExplorer.Current();
|
|
myFEIntersector.Perform(GS1,GS2);
|
|
myFEDone = ! (myFEIntersector.IsEmpty());
|
|
if (myFEDone) break;
|
|
else NextFECouple();
|
|
}
|
|
SetIntersectionDone();
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : MoreFECouple
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Boolean TopOpeBRep_ShapeIntersector::MoreFECouple() const
|
|
{
|
|
Standard_Boolean more1 = myFaceScanner.More();
|
|
Standard_Boolean more2 = myEdgeExplorer.More();
|
|
return (more1 && more2);
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : NextFECouple
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void TopOpeBRep_ShapeIntersector::NextFECouple()
|
|
{
|
|
myFaceScanner.Next();
|
|
while ( ! myFaceScanner.More() && myEdgeExplorer.More() ) {
|
|
myEdgeExplorer.Next();
|
|
myFaceScanner.Init(myEdgeExplorer);
|
|
}
|
|
}
|
|
|
|
|
|
// ========
|
|
// EFEFEFEF
|
|
// ========
|
|
|
|
|
|
//=======================================================================
|
|
//function : InitEFIntersection
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void TopOpeBRep_ShapeIntersector::InitEFIntersection()
|
|
{
|
|
if ( !myEFInit) {
|
|
TopAbs_ShapeEnum tscann = TopAbs_EDGE;
|
|
TopAbs_ShapeEnum texplo = TopAbs_FACE;
|
|
myEdgeScanner.Clear();
|
|
myEdgeScanner.AddBoxesMakeCOB(myShape1,tscann, TopAbs_FACE); // NYI defaut de spec
|
|
myFaceExplorer.Init(myShape2,texplo);
|
|
myEdgeScanner.Init(myFaceExplorer);
|
|
FindEFIntersection();
|
|
}
|
|
myEFInit = Standard_True;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : FindEFIntersection
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void TopOpeBRep_ShapeIntersector::FindEFIntersection()
|
|
{
|
|
myEFDone = Standard_False;
|
|
while ( MoreEFCouple() ) {
|
|
const TopoDS_Shape& GS1 = myEdgeScanner.Current();
|
|
const TopoDS_Shape& GS2 = myFaceExplorer.Current();
|
|
myFEIntersector.Perform(GS2,GS1);
|
|
myEFDone = ! (myFEIntersector.IsEmpty());
|
|
if (myEFDone) break;
|
|
else NextEFCouple();
|
|
}
|
|
SetIntersectionDone();
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : MoreEFCouple
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Boolean TopOpeBRep_ShapeIntersector::MoreEFCouple() const
|
|
{
|
|
Standard_Boolean more1 = myEdgeScanner.More();
|
|
Standard_Boolean more2 = myFaceExplorer.More();
|
|
return (more1 && more2);
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : NextEFCouple
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void TopOpeBRep_ShapeIntersector::NextEFCouple()
|
|
{
|
|
myEdgeScanner.Next();
|
|
while ( ! myEdgeScanner.More() && myFaceExplorer.More() ) {
|
|
myFaceExplorer.Next();
|
|
myEdgeScanner.Init(myFaceExplorer);
|
|
}
|
|
}
|
|
|
|
// ========
|
|
// EEEEEEEE
|
|
// ========
|
|
|
|
//=======================================================================
|
|
//function : InitEEIntersection
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void TopOpeBRep_ShapeIntersector::InitEEIntersection()
|
|
{
|
|
if ( ! myEEInit ) {
|
|
TopoDS_Shape face1 = myEEFace1.Oriented(TopAbs_FORWARD);
|
|
TopoDS_Shape face2 = myEEFace2.Oriented(TopAbs_FORWARD);
|
|
const TopOpeBRepTool_BoxSort& BS = myFaceScanner.BoxSort();
|
|
const Bnd_Box& B1 = BS.Box(face1);
|
|
const Bnd_Box& B2 = BS.Box(face2);
|
|
myEEIntersector.SetFaces(face1,face2,B1,B2);
|
|
|
|
TopAbs_ShapeEnum tscann = TopAbs_EDGE;
|
|
TopAbs_ShapeEnum texplo = TopAbs_EDGE;
|
|
myEdgeScanner.Clear();
|
|
myEdgeScanner.AddBoxesMakeCOB(myShape1,tscann);
|
|
myEdgeExplorer.Init(myShape2,texplo);
|
|
myEdgeScanner.Init(myEdgeExplorer);
|
|
FindEEIntersection();
|
|
}
|
|
myEEInit = Standard_True;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : FindEEIntersection
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void TopOpeBRep_ShapeIntersector::FindEEIntersection()
|
|
{
|
|
myEEDone = Standard_False;
|
|
while ( MoreEECouple() ) {
|
|
const TopoDS_Shape& GS1 = myEdgeScanner.Current();
|
|
const TopoDS_Shape& GS2 = myEdgeExplorer.Current();
|
|
myEEIntersector.Perform(GS1,GS2);
|
|
myEEDone = ! (myEEIntersector.IsEmpty());
|
|
if (myEEDone) break;
|
|
else NextEECouple();
|
|
}
|
|
SetIntersectionDone();
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : MoreEECouple
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Boolean TopOpeBRep_ShapeIntersector::MoreEECouple() const
|
|
{
|
|
Standard_Boolean more1 = myEdgeScanner.More();
|
|
Standard_Boolean more2 = myEdgeExplorer.More();
|
|
return (more1 && more2);
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : NextEECouple
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void TopOpeBRep_ShapeIntersector::NextEECouple()
|
|
{
|
|
myEdgeScanner.Next();
|
|
while ( ! myEdgeScanner.More() && myEdgeExplorer.More() ) {
|
|
myEdgeExplorer.Next();
|
|
myEdgeScanner.Init(myEdgeExplorer);
|
|
}
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : Shape
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
const TopoDS_Shape& TopOpeBRep_ShapeIntersector::Shape
|
|
( const Standard_Integer Index )const
|
|
{
|
|
if ( Index == 1 ) return myShape1;
|
|
else if ( Index == 2 ) return myShape2;
|
|
|
|
Standard_Failure::Raise("ShapeIntersector : no shape");
|
|
TopoDS_Shape* bid = new TopoDS_Shape();
|
|
return *bid;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : ChangeFacesIntersector
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
TopOpeBRep_FacesIntersector&
|
|
TopOpeBRep_ShapeIntersector::ChangeFacesIntersector()
|
|
{ return myFFIntersector; }
|
|
|
|
|
|
//=======================================================================
|
|
//function : ChangeEdgesIntersector
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
TopOpeBRep_EdgesIntersector&
|
|
TopOpeBRep_ShapeIntersector::ChangeEdgesIntersector()
|
|
{ return myEEIntersector; }
|
|
|
|
|
|
//=======================================================================
|
|
//function : ChangeFaceEdgeIntersector
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
TopOpeBRep_FaceEdgeIntersector&
|
|
TopOpeBRep_ShapeIntersector::ChangeFaceEdgeIntersector()
|
|
{ return myFEIntersector; }
|
|
|
|
|
|
//=======================================================================
|
|
//function : GetTolerances
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void TopOpeBRep_ShapeIntersector::GetTolerances(Standard_Real& tol1,
|
|
Standard_Real& tol2)const
|
|
{ tol1 = myTol1; tol2 = myTol2; }
|
|
|
|
|
|
|
|
|
|
//=======================================================================
|
|
//function : IsHalfSpaceShape
|
|
//purpose : tries to define if one of solids is a half space object
|
|
// returns:
|
|
// 0 - no half spaces ( default )
|
|
// 1 - half space is S1
|
|
// 2 - half space is S2
|
|
//=======================================================================
|
|
static Standard_Integer OneShapeIsHalfSpace(const TopoDS_Shape& S1,const TopoDS_Shape& S2)
|
|
{
|
|
Standard_Integer result = 0;
|
|
|
|
if( S1.ShapeType() == TopAbs_SOLID && S2.ShapeType() == TopAbs_SOLID )
|
|
{
|
|
TopExp_Explorer ExpSol1(S1, TopAbs_FACE);
|
|
TopExp_Explorer ExpSol2(S2, TopAbs_FACE);
|
|
Standard_Integer NbFacesSol1 = 0;
|
|
Standard_Integer NbFacesSol2 = 0;
|
|
|
|
for(; ExpSol1.More(); ExpSol1.Next() )
|
|
NbFacesSol1++;
|
|
|
|
for(; ExpSol2.More(); ExpSol2.Next() )
|
|
NbFacesSol2++;
|
|
|
|
if( NbFacesSol1 == 0 || NbFacesSol2 == 0 ) // strange solids!!!
|
|
return result;
|
|
if( NbFacesSol1 == 1 && NbFacesSol2 == 1 ) // both shapes are half spaces ???
|
|
return result;
|
|
|
|
if( (NbFacesSol1 == 1 && NbFacesSol2 >= 2) || (NbFacesSol2 == 1 && NbFacesSol1 >= 2) )
|
|
{
|
|
// if one solid has shell consisted of only a face but other one has valid closed
|
|
// shell we can detect current boolean operation as operation with half space object.
|
|
// if shell of second solid is not valid too we cann't detect what kind of objects
|
|
// we try to perform. in this case we do nothing and just return.
|
|
|
|
// but before we must avoid shperes, toruses and solids with a face biult on spherical surfaces
|
|
// of revolution (SSRFS) - solids with shell of one face:
|
|
// sphere (U: 0, 2PI) (V: -PI/2, PI/2),
|
|
// torus (U: 0, 2PI) (V: 0, 2PI).
|
|
// SSRFS (U period = (PI), 2PI) (V period = (PI), 2PI)
|
|
// these solids are not halfspaces.
|
|
|
|
TopExp_Explorer SolidExplorer;
|
|
TopoDS_Face testFace;
|
|
|
|
if( NbFacesSol1 == 1 )
|
|
{
|
|
for( SolidExplorer.Init(S1, TopAbs_FACE); SolidExplorer.More(); SolidExplorer.Next() )
|
|
testFace = TopoDS::Face( SolidExplorer.Current() );
|
|
}
|
|
else
|
|
{
|
|
for( SolidExplorer.Init(S2, TopAbs_FACE); SolidExplorer.More(); SolidExplorer.Next() )
|
|
testFace = TopoDS::Face( SolidExplorer.Current() );
|
|
}
|
|
|
|
BRepAdaptor_Surface FSurf( testFace );
|
|
Standard_Boolean SolidIsSphereOrTorus = Standard_False;
|
|
|
|
if( FSurf.GetType() == GeomAbs_Sphere || FSurf.GetType() == GeomAbs_Torus )
|
|
{
|
|
Standard_Real minU = FSurf.FirstUParameter();
|
|
Standard_Real maxU = FSurf.LastUParameter();
|
|
Standard_Real minV = FSurf.FirstVParameter();
|
|
Standard_Real maxV = FSurf.LastVParameter();
|
|
Standard_Boolean yesU = ( Abs(minU - 0.) < 1.e-9 && Abs(maxU - 2*M_PI) < 1.e-9 );
|
|
Standard_Boolean yesV = ( FSurf.GetType() == GeomAbs_Sphere ) ?
|
|
( Abs(minV - (-M_PI/2.)) < 1.e-9 && Abs(maxV - M_PI/2.) < 1.e-9 ) :
|
|
( Abs(minV - 0.) < 1.e-9 && Abs(maxV - 2*M_PI) < 1.e-9 );
|
|
SolidIsSphereOrTorus = ( yesU && yesV );
|
|
}
|
|
|
|
if( FSurf.GetType() == GeomAbs_SurfaceOfRevolution )
|
|
{
|
|
Standard_Boolean areBothPeriodic = ( FSurf.IsUPeriodic() && FSurf.IsVPeriodic() );
|
|
if( areBothPeriodic )
|
|
{
|
|
Standard_Boolean yesU = ( Abs(FSurf.UPeriod() - M_PI) < 1.e-9 || Abs(FSurf.UPeriod() - 2*M_PI) < 1.e-9 );
|
|
Standard_Boolean yesV = ( Abs(FSurf.VPeriod() - M_PI) < 1.e-9 || Abs(FSurf.VPeriod() - 2*M_PI) < 1.e-9 );
|
|
SolidIsSphereOrTorus = ( yesU && yesV );
|
|
}
|
|
}
|
|
|
|
if( SolidIsSphereOrTorus )
|
|
return result;
|
|
|
|
Standard_Boolean SecondShellOk = Standard_True;
|
|
TopTools_IndexedDataMapOfShapeListOfShape aMapEF;
|
|
aMapEF.Clear();
|
|
Standard_Integer NbEdges = 0, NbFaces = 0, iE = 0;
|
|
|
|
if( NbFacesSol1 == 1 )
|
|
TopExp::MapShapesAndAncestors(S2, TopAbs_EDGE, TopAbs_FACE, aMapEF);
|
|
else
|
|
TopExp::MapShapesAndAncestors(S1, TopAbs_EDGE, TopAbs_FACE, aMapEF);
|
|
|
|
NbEdges = aMapEF.Extent();
|
|
for( iE = 1; iE <= NbEdges; iE++)
|
|
{
|
|
const TopTools_ListOfShape& listFaces = aMapEF.FindFromIndex( iE );
|
|
NbFaces = listFaces.Extent();
|
|
if( NbFaces != 2 )
|
|
{
|
|
SecondShellOk = Standard_False;
|
|
break;
|
|
}
|
|
}
|
|
aMapEF.Clear();
|
|
|
|
if( SecondShellOk )
|
|
result = (NbFacesSol1 == 1) ? 1 : 2;
|
|
}
|
|
else
|
|
{
|
|
// ************************** IMPORTANT !!! ************************************
|
|
// both shells are of more than 2 faces. if both solids have invalid shells
|
|
// we do nothing and just return. on the other hand if only one shell is valid
|
|
// currently we should suppose that solid with invalid shell is a half space too,
|
|
// but this is not always true.
|
|
//
|
|
// so this suggestion must be developed carefully. while we don't classify it!
|
|
// *****************************************************************************
|
|
}
|
|
#ifdef DEB
|
|
if( result != 0 )
|
|
cout << "# one of the SOLIDs probably is a HALF SPACE" << endl;
|
|
#endif
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : GetNewSolid
|
|
//purpose : rebuild halfspace solid adding new "face on infinity"
|
|
// to build correct bounding box to classify carefully
|
|
// "rejected shapes".
|
|
//=======================================================================
|
|
static TopoDS_Solid GetNewSolid(const TopoDS_Shape& S, TopoDS_Face& F)
|
|
{
|
|
// "new solid" is a new halfspace solid consists of two faces now: the first face is a face
|
|
// used to build halfspace solid and the second face is a new "face on infinity" specially
|
|
// created to constuct correct bounding box around halfspace solid with bounds more wide than
|
|
// previous one.
|
|
|
|
// the following algorithm is used:
|
|
// 1. get face used to build halfspace solid and calculate its normal, Min/Max (U,V) parameters,
|
|
// four points lying on the surface of the face inside its restrictions, surface, tolerance
|
|
// and location.
|
|
// 2. define the direction into the halfspace solid and project four points along this direction
|
|
// on infinite distance. then use those points to create "face on infinity".
|
|
// 3. build new shell with two new faces and new "halfspace solid".
|
|
// 4. return this solid and "face on infinity" to remove it and all its subshapes from the list
|
|
// of rejected shapes.
|
|
|
|
TopExp_Explorer ShapeExplorer;
|
|
|
|
TopoDS_Face hsFace;
|
|
|
|
for( ShapeExplorer.Init(S, TopAbs_FACE); ShapeExplorer.More(); ShapeExplorer.Next() )
|
|
hsFace = TopoDS::Face( ShapeExplorer.Current() );
|
|
|
|
BRepAdaptor_Surface ASurf( hsFace );
|
|
|
|
Standard_Real MinU = ASurf.FirstUParameter();
|
|
Standard_Real MaxU = ASurf.LastUParameter();
|
|
Standard_Real MinV = ASurf.FirstVParameter();
|
|
Standard_Real MaxV = ASurf.LastUParameter();
|
|
|
|
Standard_Real MidU = (MaxU + MinU) * 0.5;
|
|
Standard_Real MidV = (MaxV + MinV) * 0.5;
|
|
|
|
gp_Pnt MidP;
|
|
gp_Vec SurfDU, SurfDV;
|
|
ASurf.D1( MidU, MidV, MidP, SurfDU, SurfDV );
|
|
|
|
gp_Vec Normal = SurfDU.Crossed( SurfDV );
|
|
|
|
if( hsFace.Orientation() == TopAbs_FORWARD )
|
|
Normal *= -1.e+10;
|
|
else
|
|
Normal *= 1.e+10;
|
|
|
|
Standard_Real Pu1 = MinU + Abs( (MaxU - MinU) / 4. );
|
|
Standard_Real Pu2 = MinU + Abs( (MaxU - MinU) / 4. * 3. );
|
|
Standard_Real Pv1 = MinV + Abs( (MaxV - MinV) / 4. );
|
|
Standard_Real Pv2 = MinV + Abs( (MaxV - MinV) / 4. * 3. );
|
|
|
|
gp_Pnt P1, P2, P3, P4;
|
|
ASurf.D0( Pu1, Pv1, P1 );
|
|
ASurf.D0( Pu1, Pv2, P2 );
|
|
ASurf.D0( Pu2, Pv1, P3 );
|
|
ASurf.D0( Pu2, Pv2, P4 );
|
|
|
|
P1.Translate( Normal );
|
|
P2.Translate( Normal );
|
|
P3.Translate( Normal );
|
|
P4.Translate( Normal );
|
|
|
|
BRepLib_MakeEdge mke1( P1, P2 );
|
|
BRepLib_MakeEdge mke2( P2, P4 );
|
|
BRepLib_MakeEdge mke3( P4, P3 );
|
|
BRepLib_MakeEdge mke4( P3, P1 );
|
|
|
|
TopoDS_Edge e1 = mke1.Edge();
|
|
TopoDS_Edge e2 = mke2.Edge();
|
|
TopoDS_Edge e3 = mke3.Edge();
|
|
TopoDS_Edge e4 = mke4.Edge();
|
|
|
|
BRepLib_MakeWire mkw( e1, e2, e3, e4 );
|
|
TopoDS_Wire w = mkw.Wire();
|
|
|
|
BRepLib_MakeFace mkf( w );
|
|
TopoDS_Face infFace = mkf.Face();
|
|
|
|
TopoDS_Shell newShell;
|
|
TopoDS_Solid newSolid;
|
|
|
|
BRep_Builder newShellBuilder;
|
|
newShellBuilder.MakeShell( newShell );
|
|
newShellBuilder.Add( newShell, hsFace );
|
|
newShellBuilder.Add( newShell, infFace );
|
|
|
|
BRep_Builder newSolidBuilder;
|
|
newSolidBuilder.MakeSolid( newSolid );
|
|
newSolidBuilder.Add( newSolid, newShell );
|
|
|
|
F = infFace;
|
|
return newSolid;
|
|
}
|