summaryrefslogtreecommitdiff
path: root/inc/TopOpeBRepBuild_SplitShapes.hxx
blob: 39e5881d24f76f85ccf4ce016df5dd61e4a3fcb2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
// File:	TopOpeBRepBuild_SplitShapes.hxx
// Created:	Fri Mar  1 16:24:40 1996
// Author:	Modelistation
//		<model@mentox>

#ifndef _TopOpeBRepBuild_SplitShapes_HeaderFile
#define _TopOpeBRepBuild_SplitShapes_HeaderFile

#include <Standard_ProgramError.hxx>


static Standard_Boolean FUN_touched(const TopOpeBRepDS_DataStructure& BDS,const TopoDS_Edge& EOR)
{
  TopoDS_Vertex vf,vl; TopExp::Vertices(EOR,vf,vl);
  Standard_Boolean hvf = BDS.HasShape(vf);
  Standard_Boolean hvl = BDS.HasShape(vl);
  return (hvf || hvl);
}

//=======================================================================
//function : SplitShapes
//purpose  : 
//=======================================================================
void TopOpeBRepBuild_Builder::SplitShapes(TopOpeBRepTool_ShapeExplorer& Ex,
					  const TopAbs_State ToBuild1, 
					  const TopAbs_State ToBuild2,
					  TopOpeBRepBuild_ShapeSet& aSet,
					  const Standard_Boolean RevOri)
{
  TopoDS_Shape aShape;
  TopAbs_Orientation newori;

  for (; Ex.More(); Ex.Next()) {
    aShape = Ex.Current();

    // compute new orientation <newori> to give to the new shapes
    newori = Orient(myBuildTool.Orientation(aShape),RevOri);

    TopAbs_ShapeEnum t = aShape.ShapeType();

#ifdef DEB
    if (TopOpeBRepBuild_GettraceSHEX()) GdumpEXP(Ex);
#endif

    if      ( t == TopAbs_SOLID || t == TopAbs_SHELL )
      SplitSolid(aShape,ToBuild1,ToBuild2);
    else if ( t == TopAbs_FACE  ) SplitFace(aShape,ToBuild1,ToBuild2);
    else if ( t == TopAbs_EDGE  ) SplitEdge(aShape,ToBuild1,ToBuild2);
    else continue;

    if ( IsSplit(aShape,ToBuild1) ) {
      TopoDS_Shape newShape;
      TopTools_ListIteratorOfListOfShape It;
      //----------------------- IFV
      Standard_Boolean IsLSon = Standard_False;
      //----------------------- IFV
      const TopTools_ListOfShape& LS = Splits(aShape,ToBuild1);
      //----------------------- IFV
      if(t == TopAbs_EDGE && ToBuild1 == TopAbs_IN && LS.Extent() == 0) {
	const TopTools_ListOfShape& LSon = Splits(aShape,TopAbs_ON);
	It.Initialize(LSon);
	IsLSon = Standard_True;
      }
      else {
	It.Initialize(LS);
      }
      //----------------------- IFV
      for (; It.More(); It.Next()) {
	newShape = It.Value();
	myBuildTool.Orientation(newShape,newori);
#ifdef DEB
//	TopAbs_ShapeEnum tns = TopType(newShape);
#endif
	//----------------------- IFV
	if(IsLSon) {
	  Standard_Boolean add = Standard_True;
	  if ( !myListOfFace.IsEmpty()) { // 2d pur
	    add = KeepShape(newShape,myListOfFace,ToBuild1);
	  }
	  if(add) aSet.AddStartElement(newShape);

	}
	else {
	//----------------------- IFV
	  aSet.AddStartElement(newShape);
	}
      }
    }
    else {
      // aShape n'a pas de devenir de split par ToBuild1
      // on construit les parties ToBuild1 de aShape (de S1)
      Standard_Boolean add = Standard_True;
      Standard_Boolean testkeep = Standard_False;
      Standard_Boolean isedge = (t == TopAbs_EDGE);
      Standard_Boolean hs = (myDataStructure->HasShape(aShape));
      Standard_Boolean hg = (myDataStructure->HasGeometry(aShape));
      
      testkeep = isedge && hs && (!hg);
      
      // xpu010399 : USA60299 (!hs)&&(!hg), but vertex on bound is touched (v7)
      //             -> testkeep
      Standard_Boolean istouched = isedge && (!hs) && (!hg);
      if (istouched) istouched = FUN_touched(myDataStructure->DS(),TopoDS::Edge(aShape));
      testkeep = testkeep || istouched;

      if (testkeep) { 
	if ( !myListOfFace.IsEmpty()) { // 2d pur
	  Standard_Boolean keep = KeepShape(aShape,myListOfFace,ToBuild1);
	  add = keep;
	}
	else { // 3d
	  // on classifie en solide uniqt si 
	  // E dans la DS et E a ete purgee de ses interfs car en bout
	  TopoDS_Shape sol;
	  if (STATIC_SOLIDINDEX == 1) sol = myShape2;
	  else                        sol = myShape1;
	  if ( !sol.IsNull() ) {	    
	    Standard_Real first,last;
	    Handle(Geom_Curve) C3D;
	    C3D = BRep_Tool::Curve(TopoDS::Edge(aShape),first,last);
	    if ( !C3D.IsNull() ) {
	      Standard_Real tt = 0.127956477;
	      Standard_Real par = (1-tt)*first + tt*last;
	      gp_Pnt P3D = C3D->Value(par);
	      Standard_Real tol3d = Precision::Confusion();
	      BRepClass3d_SolidClassifier SCL(sol,P3D,tol3d); 
	      TopAbs_State state = SCL.State();
	      add = (state == ToBuild1);
	    }
	    else {
	      Standard_ProgramError::Raise("SplitShapes no 3D curve on edge");
	      // NYI pas de courbe 3d : prendre un point sur (courbe 2d,face)
	    }
	  }
	  else { //  sol.IsNull
	    add = Standard_True;
	  }
	}
      }
      if ( add ) {
	myBuildTool.Orientation(aShape,newori);
	aSet.AddElement(aShape);
      }
    }

  } // Ex.More

} // SplitShapes

#endif