| 1 | // Created on: 1993-03-11 |
| 2 | // Created by: Jean Yves LEBEY |
| 3 | // Copyright (c) 1993-1999 Matra Datavision |
| 4 | // Copyright (c) 1999-2012 OPEN CASCADE SAS |
| 5 | // |
| 6 | // The content of this file is subject to the Open CASCADE Technology Public |
| 7 | // License Version 6.5 (the "License"). You may not use the content of this file |
| 8 | // except in compliance with the License. Please obtain a copy of the License |
| 9 | // at http://www.opencascade.org and read it completely before using this file. |
| 10 | // |
| 11 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its |
| 12 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. |
| 13 | // |
| 14 | // The Original Code and all software distributed under the License is |
| 15 | // distributed on an "AS IS" basis, without warranty of any kind, and the |
| 16 | // Initial Developer hereby disclaims all such warranties, including without |
| 17 | // limitation, any warranties of merchantability, fitness for a particular |
| 18 | // purpose or non-infringement. Please see the License for the specific terms |
| 19 | // and conditions governing the rights and limitations under the License. |
| 20 | |
| 21 | |
| 22 | #include <BOP_BlockBuilder.ixx> |
| 23 | |
| 24 | #include <Standard_Failure.hxx> |
| 25 | |
| 26 | //======================================================================= |
| 27 | //function : BOP_BlockBuilder::BOP_BlockBuilder |
| 28 | //purpose : |
| 29 | //======================================================================= |
| 30 | BOP_BlockBuilder::BOP_BlockBuilder() |
| 31 | : |
| 32 | myIsDone(Standard_False) |
| 33 | { |
| 34 | } |
| 35 | |
| 36 | //======================================================================= |
| 37 | //function : BOP_BlockBuilder::BOP_BlockBuilder |
| 38 | //purpose : |
| 39 | //======================================================================= |
| 40 | BOP_BlockBuilder::BOP_BlockBuilder (BOP_ShapeSet& SS) |
| 41 | :myIsDone(Standard_False) |
| 42 | { |
| 43 | MakeBlock(SS); |
| 44 | } |
| 45 | |
| 46 | //======================================================================= |
| 47 | //function : MakeBlock |
| 48 | //purpose : |
| 49 | //======================================================================= |
| 50 | void BOP_BlockBuilder::MakeBlock(BOP_ShapeSet& SS) |
| 51 | { |
| 52 | // Compute the set of connexity blocks of elements of element set SS |
| 53 | // |
| 54 | // Logic : |
| 55 | // - A block is a set of connex elements of SS |
| 56 | // - We assume that any element of SS appears in only 1 connexity block. |
| 57 | // |
| 58 | // Implementation : |
| 59 | // - All the elements of all the blocks are stored in map myOrientedShapeMap(M). |
| 60 | // - A connexity block is a segment [f,l] of element indices of M. |
| 61 | // - myBlocks is a sequence of integer; each integer is the index of the |
| 62 | // first element (in M) of a connexity block. |
| 63 | // - Bounds [f,l] of a connexity block are : |
| 64 | // f = myBlocks(i) |
| 65 | // l = myBlocks(i+1) - 1 |
| 66 | |
| 67 | myOrientedShapeMap.Clear(); |
| 68 | myOrientedShapeMapIsValid.Clear(); |
| 69 | myBlocks.Clear(); |
| 70 | myBlocksIsRegular.Clear(); |
| 71 | // |
| 72 | Standard_Boolean IsRegular, CurNei, Mextent, Eindex, |
| 73 | EnewinM, searchneighbours, condregu; |
| 74 | Standard_Integer iiregu; |
| 75 | // |
| 76 | // |
| 77 | SS.InitStartElements(); |
| 78 | for (; SS.MoreStartElements(); SS.NextStartElement()) { |
| 79 | const TopoDS_Shape& E = SS.StartElement(); |
| 80 | Mextent = myOrientedShapeMap.Extent(); |
| 81 | Eindex = AddElement(E); |
| 82 | |
| 83 | // E = current element of the element set SS |
| 84 | // Mextent = index of last element stored in map M, before E is added. |
| 85 | // Eindex = index of E added to M : Eindex > Mextent => E is new in M |
| 86 | |
| 87 | EnewinM = (Eindex > Mextent); |
| 88 | if (EnewinM) { |
| 89 | // |
| 90 | // make a new block starting at element Eindex |
| 91 | myBlocks.Append(Eindex); |
| 92 | IsRegular = Standard_True; CurNei = 0; |
| 93 | // put in current block all the elements connex to E : |
| 94 | // while an element E has been added to M |
| 95 | // - compute neighbours of E : N(E) |
| 96 | // - add each element N of N(E) to M |
| 97 | |
| 98 | Mextent = myOrientedShapeMap.Extent(); |
| 99 | searchneighbours = (Eindex <= Mextent); |
| 100 | while (searchneighbours) { |
| 101 | |
| 102 | // E = element of M on which neighbours must be searched |
| 103 | // first step : Eindex = index of starting element of SS |
| 104 | // next steps : Eindex = index of neighbours of starting element of SS |
| 105 | const TopoDS_Shape& anE = myOrientedShapeMap(Eindex); |
| 106 | CurNei = SS.MaxNumberSubShape(anE); |
| 107 | |
| 108 | condregu = (CurNei > 2) ? Standard_False : Standard_True; |
| 109 | |
| 110 | IsRegular = IsRegular && condregu; |
| 111 | // |
| 112 | // compute neighbours of E : add them to M to increase M.Extent(). |
| 113 | SS.InitNeighbours(anE); |
| 114 | |
| 115 | for (; SS.MoreNeighbours(); SS.NextNeighbour()) { |
| 116 | const TopoDS_Shape& N = SS.Neighbour(); |
| 117 | AddElement(N); |
| 118 | } |
| 119 | |
| 120 | Eindex++; |
| 121 | Mextent = myOrientedShapeMap.Extent(); |
| 122 | searchneighbours = (Eindex <= Mextent); |
| 123 | |
| 124 | } // while (searchneighbours) |
| 125 | |
| 126 | iiregu = IsRegular ? 1 : 0; |
| 127 | myBlocksIsRegular.Append(iiregu); |
| 128 | } // if (EnewinM) |
| 129 | } // for () |
| 130 | // |
| 131 | // To value the l bound of the last connexity block created above, |
| 132 | // we create an artificial block of value = myOrientedShapeMap.Extent() + 1 |
| 133 | // The real number of connexity blocks is myBlocks.Length() - 1 |
| 134 | Mextent = myOrientedShapeMap.Extent(); |
| 135 | myBlocks.Append(Mextent + 1); |
| 136 | |
| 137 | myIsDone = Standard_True; |
| 138 | } |
| 139 | |
| 140 | //======================================================================= |
| 141 | //function : InitBlock |
| 142 | //purpose : |
| 143 | //======================================================================= |
| 144 | void BOP_BlockBuilder::InitBlock() |
| 145 | { |
| 146 | myBlockIndex = 1; |
| 147 | } |
| 148 | |
| 149 | //======================================================================= |
| 150 | //function : MoreBlock |
| 151 | //purpose : |
| 152 | //======================================================================= |
| 153 | Standard_Boolean BOP_BlockBuilder::MoreBlock() const |
| 154 | { |
| 155 | // the length of myBlocks is 1 + number of connexity blocks |
| 156 | Standard_Integer l = myBlocks.Length(); |
| 157 | Standard_Boolean b = (myBlockIndex < l); |
| 158 | return b; |
| 159 | } |
| 160 | |
| 161 | //======================================================================= |
| 162 | //function : NextBlock |
| 163 | //purpose : |
| 164 | //======================================================================= |
| 165 | void BOP_BlockBuilder::NextBlock() |
| 166 | { |
| 167 | myBlockIndex++; |
| 168 | } |
| 169 | |
| 170 | //======================================================================= |
| 171 | //function : BlockIterator |
| 172 | //purpose : |
| 173 | //======================================================================= |
| 174 | BOP_BlockIterator BOP_BlockBuilder::BlockIterator() const |
| 175 | { |
| 176 | Standard_Integer lower, upper; |
| 177 | |
| 178 | lower = myBlocks(myBlockIndex); |
| 179 | upper = myBlocks(myBlockIndex+1)-1; |
| 180 | |
| 181 | return BOP_BlockIterator(lower,upper); |
| 182 | } |
| 183 | |
| 184 | //======================================================================= |
| 185 | //function : Element |
| 186 | //purpose : |
| 187 | //======================================================================= |
| 188 | const TopoDS_Shape& BOP_BlockBuilder::Element (const BOP_BlockIterator& BI) const |
| 189 | { |
| 190 | Standard_Boolean isbound = BI.More(); |
| 191 | if (!isbound) { |
| 192 | Standard_Failure::Raise("OutOfRange"); |
| 193 | } |
| 194 | |
| 195 | Standard_Integer index = BI.Value(); |
| 196 | const TopoDS_Shape& E = myOrientedShapeMap(index); |
| 197 | return E; |
| 198 | } |
| 199 | //======================================================================= |
| 200 | //function : Element |
| 201 | //purpose : |
| 202 | //======================================================================= |
| 203 | const TopoDS_Shape& BOP_BlockBuilder::Element (const Standard_Integer index) const |
| 204 | { |
| 205 | Standard_Boolean isbound = myOrientedShapeMapIsValid.IsBound(index); |
| 206 | if (!isbound) { |
| 207 | Standard_Failure::Raise("OutOfRange"); |
| 208 | } |
| 209 | const TopoDS_Shape& E = myOrientedShapeMap(index); |
| 210 | return E; |
| 211 | } |
| 212 | //======================================================================= |
| 213 | //function : Element |
| 214 | //purpose : |
| 215 | //======================================================================= |
| 216 | Standard_Integer BOP_BlockBuilder::Element (const TopoDS_Shape& E) const |
| 217 | { |
| 218 | Standard_Boolean isbound = myOrientedShapeMap.Contains(E); |
| 219 | if (!isbound) { |
| 220 | Standard_Failure::Raise("OutOfRange"); |
| 221 | } |
| 222 | |
| 223 | Standard_Integer I = myOrientedShapeMap.FindIndex(E); |
| 224 | return I; |
| 225 | } |
| 226 | |
| 227 | //======================================================================= |
| 228 | //function : ElementIsValid |
| 229 | //purpose : |
| 230 | //======================================================================= |
| 231 | Standard_Boolean BOP_BlockBuilder::ElementIsValid (const BOP_BlockIterator& BI) const |
| 232 | { |
| 233 | Standard_Boolean isvalid, isbound = BI.More(); |
| 234 | if (!isbound) { |
| 235 | return Standard_False; |
| 236 | } |
| 237 | Standard_Integer Sindex, isb; |
| 238 | |
| 239 | Sindex = BI.Value(); |
| 240 | isb = myOrientedShapeMapIsValid.Find(Sindex); |
| 241 | isvalid = (isb == 1)? Standard_True: Standard_False; |
| 242 | |
| 243 | return isvalid; |
| 244 | } |
| 245 | //======================================================================= |
| 246 | //function : ElementIsValid |
| 247 | //purpose : |
| 248 | //======================================================================= |
| 249 | Standard_Boolean BOP_BlockBuilder::ElementIsValid (const Standard_Integer Sindex) const |
| 250 | { |
| 251 | Standard_Boolean isvalid, isbound = myOrientedShapeMapIsValid.IsBound(Sindex); |
| 252 | if (!isbound) return Standard_False; |
| 253 | |
| 254 | Standard_Integer isb = myOrientedShapeMapIsValid.Find(Sindex); |
| 255 | isvalid = (isb == 1)? Standard_True: Standard_False; |
| 256 | |
| 257 | return isvalid; |
| 258 | } |
| 259 | |
| 260 | //======================================================================= |
| 261 | //function : AddElement |
| 262 | //purpose : |
| 263 | //======================================================================= |
| 264 | Standard_Integer BOP_BlockBuilder::AddElement(const TopoDS_Shape& S) |
| 265 | { |
| 266 | Standard_Integer Sindex = myOrientedShapeMap.Add(S); |
| 267 | myOrientedShapeMapIsValid.Bind(Sindex, 1); |
| 268 | |
| 269 | return Sindex; |
| 270 | } |
| 271 | |
| 272 | //======================================================================= |
| 273 | //function : SetValid |
| 274 | //purpose : |
| 275 | //======================================================================= |
| 276 | void BOP_BlockBuilder::SetValid(const BOP_BlockIterator& BI, |
| 277 | const Standard_Boolean isvalid) |
| 278 | { |
| 279 | Standard_Boolean isbound = BI.More(); |
| 280 | if (!isbound) { |
| 281 | return; |
| 282 | } |
| 283 | Standard_Integer Sindex, i; |
| 284 | Sindex = BI.Value(); |
| 285 | i = (isvalid) ? 1 : 0; |
| 286 | myOrientedShapeMapIsValid.Bind(Sindex,i); |
| 287 | } |
| 288 | //======================================================================= |
| 289 | //function : SetValid |
| 290 | //purpose : |
| 291 | //======================================================================= |
| 292 | void BOP_BlockBuilder::SetValid(const Standard_Integer Sindex, |
| 293 | const Standard_Boolean isvalid) |
| 294 | { |
| 295 | Standard_Boolean isbound = myOrientedShapeMapIsValid.IsBound(Sindex); |
| 296 | if (!isbound) { |
| 297 | return; |
| 298 | } |
| 299 | |
| 300 | Standard_Integer i = (isvalid) ? 1 : 0; |
| 301 | myOrientedShapeMapIsValid.Bind(Sindex,i); |
| 302 | } |
| 303 | |
| 304 | //======================================================================= |
| 305 | //function : CurrentBlockIsRegular |
| 306 | //purpose : |
| 307 | //======================================================================= |
| 308 | Standard_Boolean BOP_BlockBuilder::CurrentBlockIsRegular() |
| 309 | { |
| 310 | Standard_Boolean b = Standard_False; |
| 311 | Standard_Integer i = myBlocksIsRegular.Value(myBlockIndex); |
| 312 | |
| 313 | if(i == 1) { |
| 314 | b = Standard_True; |
| 315 | } |
| 316 | return b; |
| 317 | } |
| 318 | |
| 319 | |