summaryrefslogtreecommitdiff
path: root/src/ShapeBuild/ShapeBuild_ReShape.cxx
blob: 79f7b1923e8446f2f3c666297e17552d5ae9c520 (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
//    abv 28.04.99 S4137: ading method Apply for work on all types of shapes

#include <ShapeBuild_ReShape.ixx>

#include <TopoDS_Shell.hxx>
#include <TopoDS_Solid.hxx>
#include <TopoDS_Compound.hxx>
#include <TopoDS_Iterator.hxx>
#include <TopExp_Explorer.hxx>
#include <BRep_Builder.hxx>
#include <ShapeExtend.hxx>
#include <ShapeBuild_Edge.hxx>
#include <TopoDS.hxx>

//=======================================================================
//function : ShapeBuild_ReShape
//purpose  : 
//=======================================================================

ShapeBuild_ReShape::ShapeBuild_ReShape()
{
}

//=======================================================================
//function : Apply
//purpose  : 
//=======================================================================

TopoDS_Shape ShapeBuild_ReShape::Apply (const TopoDS_Shape& shape,
					const TopAbs_ShapeEnum until,
					const Standard_Integer buildmode) 
{
  return BRepTools_ReShape::Apply (shape,until,buildmode);
}

//=======================================================================
//function : Apply
//purpose  : 
//=======================================================================

TopoDS_Shape ShapeBuild_ReShape::Apply (const TopoDS_Shape& shape,
					const TopAbs_ShapeEnum until) 
{
  myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK );
  if ( shape.IsNull() ) return shape;

  // apply direct replacement
  TopoDS_Shape newsh = Value ( shape );
  
  // if shape removed, return NULL
  if ( newsh.IsNull() ) {
    myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_DONE2 );
    return newsh;
  }
  
  // if shape replaced, apply modifications to the result recursively 
  Standard_Boolean aConsLoc = ModeConsiderLocation();
  if ( (aConsLoc && ! newsh.IsPartner (shape)) || 
      (!aConsLoc &&! newsh.IsSame ( shape )) ) {
  
    TopoDS_Shape res = Apply ( newsh, until );
    myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 );
    return res;
  }

  TopAbs_ShapeEnum st = shape.ShapeType();
  if ( st >= until ) return newsh;    // critere d arret
  if(st == TopAbs_VERTEX || st == TopAbs_SHAPE)
    return shape;
  // define allowed types of components

  BRep_Builder B;
  
  TopoDS_Shape result = shape.EmptyCopied();
  TopAbs_Orientation orient = shape.Orientation(); //JR/Hp: or -> orient
  result.Orientation(TopAbs_FORWARD); // protect against INTERNAL or EXTERNAL shapes
  Standard_Boolean modif = Standard_False;
  Standard_Integer locStatus = myStatus;
  
  // apply recorded modifications to subshapes
  for ( TopoDS_Iterator it(shape,Standard_False); it.More(); it.Next() ) {
    TopoDS_Shape sh = it.Value();
    newsh = Apply ( sh, until );
    if ( newsh != sh ) {
      if ( ShapeExtend::DecodeStatus ( myStatus, ShapeExtend_DONE4 ) )
	locStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE4 );
      modif = 1;
    }
    if ( newsh.IsNull() ) {
      locStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE4 );
      continue;
    }
    locStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE3 );
    if ( st == TopAbs_COMPOUND || newsh.ShapeType() == sh.ShapeType()) { //fix for SAMTECH bug OCC322 about abcense internal vertices after sewing.
      B.Add ( result, newsh );
      continue;
    }
    Standard_Integer nitems = 0;
    for ( TopoDS_Iterator subit(newsh); subit.More(); subit.Next(), nitems++ ) {
      TopoDS_Shape subsh = subit.Value();
      if ( subsh.ShapeType() == sh.ShapeType() ) B.Add ( result, subsh );
      else locStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL1 );
    }
    if ( ! nitems ) locStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL1 );
  }
  if ( ! modif ) return shape;

  // restore Range on edge broken by EmptyCopied()
  if ( st == TopAbs_EDGE ) {
    ShapeBuild_Edge sbe;
    sbe.CopyRanges ( TopoDS::Edge ( result ), TopoDS::Edge ( shape ));
  }
  result.Orientation(orient);
  myStatus = locStatus;
  Replace ( shape, result );
  return result;
}

//=======================================================================
//function : Status
//purpose  : 
//=======================================================================

Standard_Integer ShapeBuild_ReShape::Status(const TopoDS_Shape& ashape,
					    TopoDS_Shape& newsh,
					    const Standard_Boolean last) 
{
  return BRepTools_ReShape::Status(ashape,newsh,last);
}

//=======================================================================
//function : Status
//purpose  : 
//=======================================================================

Standard_Boolean ShapeBuild_ReShape::Status (const ShapeExtend_Status status) const
{
  return ShapeExtend::DecodeStatus ( myStatus, status );
}