summaryrefslogtreecommitdiff
path: root/src/TopOpeBRepBuild/TopOpeBRepBuild_BlockBuilder.cxx
blob: 6d186e56221d602b9451b916bce4767515a94c10 (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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
// File:	TopOpeBRepBuild_BlockBuilder.cxx
// Created:	Thu Mar 11 12:56:30 1993
// Author:	Jean Yves LEBEY
//		<jyl@sdsun2>
// Copyright:    Matra Datavision	

#include <TopOpeBRepBuild_BlockBuilder.ixx>
#include <Standard_Failure.hxx>

//=======================================================================
//function : TopOpeBRepBuild_BlockBuilder
//purpose  : 
//=======================================================================

TopOpeBRepBuild_BlockBuilder::TopOpeBRepBuild_BlockBuilder()
:myIsDone(Standard_False)
{
}

//=======================================================================
//function : TopOpeBRepBuild_BlockBuilder
//purpose  : 
//=======================================================================

TopOpeBRepBuild_BlockBuilder::TopOpeBRepBuild_BlockBuilder 
(TopOpeBRepBuild_ShapeSet& SS)
:myIsDone(Standard_False)
{
  MakeBlock(SS);
}

//=======================================================================
//function : MakeBlock
//purpose  : 
//=======================================================================

void TopOpeBRepBuild_BlockBuilder::MakeBlock(TopOpeBRepBuild_ShapeSet& SS)
{
  // Compute the set of connexity blocks of elements of element set SS
  //
  // Logic : 
  // - A block is a set of connex elements of SS
  // - We assume that any element of SS appears in only 1 connexity block.
  //
  // Implementation :
  // - All the elements of all the blocks are stored in map myOrientedShapeMap(M).
  // - A connexity block is a segment [f,l] of element indices of M.
  // - myBlocks is a sequence of integer; each integer is the index of the 
  //   first element (in M) of a connexity block.
  // - Bounds [f,l] of a connexity block are : 
  //    f = myBlocks(i)
  //    l = myBlocks(i+1) - 1

  myOrientedShapeMap.Clear();
  myOrientedShapeMapIsValid.Clear();
  myBlocks.Clear();
  myBlocksIsRegular.Clear();
  
  Standard_Boolean IsRegular;
  Standard_Integer CurNei;
  Standard_Integer Mextent;
  Standard_Integer Eindex;

  for (SS.InitStartElements();SS.MoreStartElements();SS.NextStartElement()) {

    const TopoDS_Shape& E = SS.StartElement(); 
    Mextent = myOrientedShapeMap.Extent();
    Eindex = AddElement(E); 

    // E = current element of the element set SS
    // Mextent = index of last element stored in map M, before E is added. 
    // Eindex  = index of E added to M : Eindex > Mextent => E is new in M

    Standard_Boolean EnewinM = (Eindex > Mextent);
    if (EnewinM) {

      // make a new block starting at element Eindex
      myBlocks.Append(Eindex);
      IsRegular = Standard_True; CurNei = 0;
      // put in current block all the elements connex to E :
      // while an element E has been added to M
      //    - compute neighbours of E : N(E)
      //    - add each element N of N(E) to M

      Mextent = myOrientedShapeMap.Extent();
      Standard_Boolean searchneighbours = (Eindex <= Mextent);
      while (searchneighbours) {

	// E = element of M on which neighbours must be searched
	// first step : Eindex = index of starting element of SS
	// next steps : Eindex = index of neighbours of starting element of SS 
	const TopoDS_Shape& E1 = myOrientedShapeMap(Eindex);
	CurNei = SS.MaxNumberSubShape(E1);
	Standard_Boolean condregu = Standard_True;
	if (CurNei > 2) condregu = Standard_False;
	IsRegular = IsRegular && condregu;
	// compute neighbours of E : add them to M to increase M.Extent().
	SS.InitNeighbours(E1);

	for (; SS.MoreNeighbours(); SS.NextNeighbour()) {
	  const TopoDS_Shape& N = SS.Neighbour();
	  AddElement(N);
	}
	
	Eindex++;
	Mextent = myOrientedShapeMap.Extent();
	searchneighbours = (Eindex <= Mextent);
	
      } // while (searchneighbours)
      Standard_Integer iiregu = IsRegular ? 1 : 0;
      myBlocksIsRegular.Append(iiregu);      
    } // if (EnewinM)
  } // for ()
  
  // To value the l bound of the last connexity block created above,
  // we create an artificial block of value = myOrientedShapeMap.Extent() + 1
  // The real number of connexity blocks is myBlocks.Length() - 1
  Mextent = myOrientedShapeMap.Extent();
  myBlocks.Append(Mextent + 1);
  myIsDone = Standard_True;

#if 0
// version seche
  myOrientedShapeMap.Clear();
  myOrientedShapeMapIsValid.Clear();
  myBlocks.Clear();
  while (SS.MoreStartElements()) {
    Standard_Integer last = myOrientedShapeMap.Extent();
    Standard_Integer index =AddElement(SS.StartElement());
    if (index > last) {
      myBlocks.Append(index);
      while (index <= myOrientedShapeMap.Extent()) {
	for (SS.InitNeighbours(myOrientedShapeMap(index));
	     SS.MoreNeighbours();
	     SS.NextNeighbour()) {
	 AddElement(SS.Neighbour());
	}
	index++;
      }
    }
    SS.NextStartElement();
  }
  myBlocks.Append(myOrientedShapeMap.Extent()+1);
  myBlockIndex = 1;
#endif
}

//=======================================================================
//function : InitBlock
//purpose  : 
//=======================================================================

void TopOpeBRepBuild_BlockBuilder::InitBlock()
{
  myBlockIndex = 1;
}

//=======================================================================
//function : MoreBlock
//purpose  : 
//=======================================================================

Standard_Boolean TopOpeBRepBuild_BlockBuilder::MoreBlock() const
{
  // the length of myBlocks is 1 + number of connexity blocks
  Standard_Integer l =  myBlocks.Length();
  Standard_Boolean b = (myBlockIndex < l);
  return b;
}

//=======================================================================
//function : NextBlock
//purpose  : 
//=======================================================================

void TopOpeBRepBuild_BlockBuilder::NextBlock()
{
  myBlockIndex++;
}

//=======================================================================
//function : BlockIterator
//purpose  : 
//=======================================================================

TopOpeBRepBuild_BlockIterator TopOpeBRepBuild_BlockBuilder::BlockIterator() const
{
  Standard_Integer lower = myBlocks(myBlockIndex);
  Standard_Integer upper = myBlocks(myBlockIndex+1)-1;
  return TopOpeBRepBuild_BlockIterator(lower,upper);
}

//=======================================================================
//function : Element
//purpose  : 
//=======================================================================

const TopoDS_Shape& TopOpeBRepBuild_BlockBuilder::Element 
(const TopOpeBRepBuild_BlockIterator& BI) const
{
  Standard_Boolean isbound = BI.More();
  if (!isbound) Standard_Failure::Raise("OutOfRange");

  Standard_Integer index = BI.Value();
  const TopoDS_Shape& E = myOrientedShapeMap(index);
  return E;
} 

const TopoDS_Shape& TopOpeBRepBuild_BlockBuilder::Element 
(const Standard_Integer index) const
{
  Standard_Boolean isbound = myOrientedShapeMapIsValid.IsBound(index);
  if (!isbound) Standard_Failure::Raise("OutOfRange");

  const TopoDS_Shape& E = myOrientedShapeMap(index);
  return E;
} 

Standard_Integer TopOpeBRepBuild_BlockBuilder::Element 
(const TopoDS_Shape& E) const
{
  Standard_Boolean isbound = myOrientedShapeMap.Contains(E);
  if (!isbound) Standard_Failure::Raise("OutOfRange");

  Standard_Integer I = myOrientedShapeMap.FindIndex(E);
  return I;
}

//=======================================================================
//function : ElementIsValid
//purpose  : 
//=======================================================================

Standard_Boolean TopOpeBRepBuild_BlockBuilder::ElementIsValid
(const TopOpeBRepBuild_BlockIterator& BI) const 
{  
  Standard_Boolean isbound = BI.More();
  if (!isbound) return Standard_False;

  Standard_Integer Sindex = BI.Value();
  Standard_Integer isb = myOrientedShapeMapIsValid.Find(Sindex);
  Standard_Boolean isvalid = (isb == 1)? Standard_True: Standard_False;
  
  return isvalid;
}

Standard_Boolean TopOpeBRepBuild_BlockBuilder::ElementIsValid
(const Standard_Integer Sindex) const
{  
  Standard_Boolean isbound = myOrientedShapeMapIsValid.IsBound(Sindex);
  if (!isbound) return Standard_False;

  Standard_Integer isb = myOrientedShapeMapIsValid.Find(Sindex);
  Standard_Boolean isvalid = (isb == 1)? Standard_True: Standard_False;
  
  return isvalid;
}

//=======================================================================
//function : AddElement
//purpose  : 
//=======================================================================

Standard_Integer TopOpeBRepBuild_BlockBuilder::AddElement(const TopoDS_Shape& S) 
{
  Standard_Integer Sindex = myOrientedShapeMap.Add(S);
  myOrientedShapeMapIsValid.Bind(Sindex, 1);

  return Sindex;
}

//=======================================================================
//function : SetValid
//purpose  : 
//=======================================================================

void TopOpeBRepBuild_BlockBuilder::SetValid
(const TopOpeBRepBuild_BlockIterator& BI,
 const Standard_Boolean isvalid)
{
  Standard_Boolean isbound = BI.More();
  if (!isbound) return;

  Standard_Integer Sindex = BI.Value();
  Standard_Integer i = (isvalid) ? 1 : 0;
  myOrientedShapeMapIsValid.Bind(Sindex,i);
}

void TopOpeBRepBuild_BlockBuilder::SetValid
(const Standard_Integer Sindex,
 const Standard_Boolean isvalid)
{
  Standard_Boolean isbound = myOrientedShapeMapIsValid.IsBound(Sindex);
  if (!isbound) return;

  Standard_Integer i = (isvalid) ? 1 : 0;
  myOrientedShapeMapIsValid.Bind(Sindex,i);
}

//=======================================================================
//function : CurrentBlockIsRegular
//purpose  : 
//=======================================================================

Standard_Boolean TopOpeBRepBuild_BlockBuilder::CurrentBlockIsRegular()
{
  Standard_Boolean b = Standard_False;
  Standard_Integer i = myBlocksIsRegular.Value(myBlockIndex);
  if(i == 1)
    b = Standard_True;
  return b;
}