| 1 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
| 2 | // |
| 3 | // This file is part of Open CASCADE Technology software library. |
| 4 | // |
| 5 | // This library is free software; you can redistribute it and/or modify it under |
| 6 | // the terms of the GNU Lesser General Public License version 2.1 as published |
| 7 | // by the Free Software Foundation, with special exception defined in the file |
| 8 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
| 9 | // distribution for complete text of the license and disclaimer of any warranty. |
| 10 | // |
| 11 | // Alternatively, this file may be used under the terms of Open CASCADE |
| 12 | // commercial license or contractual agreement. |
| 13 | |
| 14 | //#73 rln 10.03.99 S4135: "read.scale.unit" does not affect GlobalSection |
| 15 | #include <IGESData_BasicEditor.ixx> |
| 16 | |
| 17 | #include <Interface_Graph.hxx> |
| 18 | #include <Interface_EntityIterator.hxx> |
| 19 | #include <IGESData_GeneralModule.hxx> |
| 20 | #include <IGESData_SpecificModule.hxx> |
| 21 | |
| 22 | #include <TCollection_HAsciiString.hxx> |
| 23 | #include <TColStd_Array1OfInteger.hxx> |
| 24 | |
| 25 | #include <IGESData_LineFontEntity.hxx> |
| 26 | #include <IGESData_LevelListEntity.hxx> |
| 27 | #include <IGESData_ViewKindEntity.hxx> |
| 28 | #include <IGESData_TransfEntity.hxx> |
| 29 | #include <IGESData_LabelDisplayEntity.hxx> |
| 30 | #include <IGESData_ColorEntity.hxx> |
| 31 | #include <IGESData_DirChecker.hxx> |
| 32 | |
| 33 | #include <Interface_Static.hxx> |
| 34 | #include <Interface_Macros.hxx> |
| 35 | #include <UnitsMethods.hxx> |
| 36 | |
| 37 | |
| 38 | IGESData_BasicEditor::IGESData_BasicEditor(const Handle(IGESData_Protocol)& protocol) |
| 39 | { |
| 40 | Init(protocol); |
| 41 | } |
| 42 | |
| 43 | IGESData_BasicEditor::IGESData_BasicEditor(const Handle(IGESData_IGESModel)& model, |
| 44 | const Handle(IGESData_Protocol)& protocol) |
| 45 | { |
| 46 | Init(model, protocol); |
| 47 | } |
| 48 | |
| 49 | IGESData_BasicEditor::IGESData_BasicEditor() { } |
| 50 | |
| 51 | void IGESData_BasicEditor::Init (const Handle(IGESData_Protocol)& protocol) |
| 52 | { |
| 53 | theunit = Standard_False; |
| 54 | theproto = protocol; |
| 55 | themodel = GetCasted(IGESData_IGESModel,Interface_InterfaceModel::Template("iges")); |
| 56 | theglib = protocol; |
| 57 | theslib = protocol; |
| 58 | } |
| 59 | |
| 60 | void IGESData_BasicEditor::Init (const Handle(IGESData_IGESModel)& model, const Handle(IGESData_Protocol)& protocol) |
| 61 | { |
| 62 | theunit = Standard_False; |
| 63 | theproto = protocol; |
| 64 | themodel = model; |
| 65 | theglib = protocol; |
| 66 | theslib = protocol; |
| 67 | } |
| 68 | |
| 69 | Handle(IGESData_IGESModel) IGESData_BasicEditor::Model () const |
| 70 | { return themodel; } |
| 71 | |
| 72 | // #### Travaux sur le Header (GlobalSection) #### |
| 73 | |
| 74 | Standard_Boolean IGESData_BasicEditor::SetUnitFlag |
| 75 | (const Standard_Integer flag) |
| 76 | { |
| 77 | if (themodel.IsNull()) return Standard_False; |
| 78 | if (flag < 1 || flag > 11) return Standard_False; |
| 79 | IGESData_GlobalSection GS = themodel->GlobalSection(); |
| 80 | Handle(TCollection_HAsciiString) name = GS.UnitName(); |
| 81 | Standard_CString nam = IGESData_BasicEditor::UnitFlagName (flag); |
| 82 | if (nam[0] != '\0') name = new TCollection_HAsciiString (nam); |
| 83 | GS.SetUnitFlag (flag); |
| 84 | GS.SetUnitName (name); |
| 85 | themodel->SetGlobalSection (GS); |
| 86 | theunit = Standard_True; |
| 87 | return Standard_True; |
| 88 | } |
| 89 | |
| 90 | Standard_Boolean IGESData_BasicEditor::SetUnitValue |
| 91 | (const Standard_Real val) |
| 92 | { |
| 93 | if (val <= 0.) return Standard_False; |
| 94 | Standard_Real vmm = val * UnitsMethods::GetCasCadeLengthUnit(); //abv 20 Feb 00: adding cascade unit factor |
| 95 | //#73 rln 10.03.99 S4135: "read.scale.unit" does not affect GlobalSection |
| 96 | //if (Interface_Static::IVal("read.scale.unit") == 1) vmm = vmm * 1000.; |
| 97 | // vmm est exprime en MILLIMETRES |
| 98 | if (vmm >= 25. && vmm <= 26. ) return SetUnitFlag(1); |
| 99 | if (vmm >= 0.9 && vmm <= 1.1 ) return SetUnitFlag(2); |
| 100 | if (vmm >= 300. && vmm <= 310. ) return SetUnitFlag(4); |
| 101 | if (vmm >= 1600000. && vmm <= 1620000. ) return SetUnitFlag(5); |
| 102 | if (vmm >= 990. && vmm <= 1010. ) return SetUnitFlag(6); |
| 103 | if (vmm >= 990000. && vmm <= 1010000. ) return SetUnitFlag(7); |
| 104 | if (vmm >= 0.025 && vmm <= 0.026 ) return SetUnitFlag(8); |
| 105 | if (vmm >= 0.0009 && vmm <= 0.0011 ) return SetUnitFlag(9); |
| 106 | if (vmm >= 9. && vmm <= 11. ) return SetUnitFlag(10); |
| 107 | if (vmm >= 0.000025 && vmm <= 0.000026) return SetUnitFlag(11); |
| 108 | return Standard_False; |
| 109 | } |
| 110 | |
| 111 | //======================================================================= |
| 112 | //function : SetUnitName |
| 113 | //purpose : |
| 114 | //======================================================================= |
| 115 | Standard_Boolean IGESData_BasicEditor::SetUnitName (const Standard_CString name) |
| 116 | { |
| 117 | if (themodel.IsNull()) return Standard_False; |
| 118 | Standard_Integer flag = IGESData_BasicEditor::UnitNameFlag (name); |
| 119 | IGESData_GlobalSection GS = themodel->GlobalSection(); |
| 120 | if (GS.UnitFlag() == 3) { |
| 121 | char* nam = (char *)name; |
| 122 | if (name[1] == 'H') nam = (char *)&name[2]; |
| 123 | GS.SetUnitName (new TCollection_HAsciiString(nam)); |
| 124 | themodel->SetGlobalSection (GS); |
| 125 | return Standard_True; |
| 126 | } |
| 127 | if (flag > 0) return SetUnitFlag(flag); |
| 128 | return (flag > 0); |
| 129 | } |
| 130 | |
| 131 | void IGESData_BasicEditor::ApplyUnit (const Standard_Boolean enforce) |
| 132 | { |
| 133 | if (themodel.IsNull()) return; |
| 134 | if (!enforce && !theunit) return; |
| 135 | IGESData_GlobalSection GS = themodel->GlobalSection(); |
| 136 | Standard_Real unit = GS.UnitValue(); |
| 137 | if (unit <= 0.) return; |
| 138 | if (unit != 1.) { |
| 139 | GS.SetMaxLineWeight (GS.MaxLineWeight () / unit); |
| 140 | GS.SetResolution (GS.Resolution () / unit); |
| 141 | GS.SetMaxCoord (GS.MaxCoord () / unit); |
| 142 | themodel->SetGlobalSection (GS); |
| 143 | } |
| 144 | theunit = Standard_False; |
| 145 | } |
| 146 | |
| 147 | |
| 148 | // #### Travaux globaux sur les entites #### |
| 149 | |
| 150 | void IGESData_BasicEditor::ComputeStatus () |
| 151 | { |
| 152 | if (themodel.IsNull()) return; |
| 153 | Standard_Integer nb = themodel->NbEntities(); |
| 154 | if (nb == 0) return; |
| 155 | TColStd_Array1OfInteger subs (0,nb); subs.Init(0); // gere Subordinate Status |
| 156 | Interface_Graph G (themodel,theglib); // gere & memorise UseFlag |
| 157 | G.ResetStatus(); |
| 158 | |
| 159 | // 2 phases : d abord on fait un calcul d ensemble. Ensuite on applique |
| 160 | // Tout le modele est traite, pas de jaloux |
| 161 | |
| 162 | // Chaque entite va donner une contribution sur ses descendents propres : |
| 163 | // pour Subordinate (1 ou 2 cumulables), pour UseFlag (1 a 6 exclusifs) |
| 164 | // (6 depuis IGES-5.2) |
| 165 | |
| 166 | // Pour Subordinate : Drawing et 402 (sauf p-e dimensioned geometry ?) donnent |
| 167 | // Logical, le reste implique Physical (sur descendants directs propres) |
| 168 | |
| 169 | // Pour UseFlag, un peu plus complique : |
| 170 | // D une part, les UseFlag se propagent aux descendants directs ou non |
| 171 | // D autre part les cas sont plus compliques (et pas aussi clairs) |
| 172 | |
| 173 | // ATTENTION, on ne peut traiter que ce qui se deduit du graphe en s appuyant |
| 174 | // sur les "IGES Type Number", on n a pas le droit ici d acceder a la |
| 175 | // description specifique des differents types : traites par AutoCorrect. |
| 176 | // Exemple : une courbe est 3D ou parametrique 2D(UV), non seulement selon son |
| 177 | // ascendant, mais selon le role qu elle y joue (ex. pour CurveOnSurface : |
| 178 | // CurveUV/Curve3D) |
| 179 | // Traites actuellement (necessaires) : |
| 180 | // 1(Annotation), aussi 4(pour maillage). 5(ParamUV) traite par AutoCorrect |
| 181 | |
| 182 | Handle(IGESData_GeneralModule) gmod; |
| 183 | Standard_Integer CN; |
| 184 | Standard_Integer i; // svv Jan11 2000 : porting on DEC |
| 185 | for (i = 1; i <= nb; i ++) { |
| 186 | // Subordinate (sur directs en propre seulement) |
| 187 | Handle(IGESData_IGESEntity) ent = themodel->Entity(i); |
| 188 | Standard_Integer igt = ent->TypeNumber(); |
| 189 | if (theglib.Select (ent,gmod,CN)) { |
| 190 | Interface_EntityIterator sh; |
| 191 | gmod->OwnSharedCase (CN,ent,sh); |
| 192 | for (sh.Start(); sh.More(); sh.Next()) { |
| 193 | Standard_Integer nums = themodel->Number(sh.Value()); |
| 194 | if (igt == 402 || igt == 404) subs.SetValue (nums,subs.Value(nums) | 2); |
| 195 | else subs.SetValue (nums,subs.Value(nums) | 1); |
| 196 | //// cout<<"ComputeStatus : nums = "<<nums<<" ->"<<subs.Value(nums)<<endl; |
| 197 | } |
| 198 | } |
| 199 | // UseFlag (a propager) |
| 200 | if (igt / 100 == 2) { |
| 201 | G.GetFromEntity(ent,Standard_True,1); // Annotation |
| 202 | G.GetFromEntity(ent,Standard_False,ent->UseFlag()); |
| 203 | } else if (igt == 134 || igt == 116 || igt == 132) { |
| 204 | Interface_EntityIterator sh = G.Sharings(ent); // Maillage ... |
| 205 | if (sh.NbEntities() > 0) G.GetFromEntity(ent,Standard_True,4); |
| 206 | // UV : voir AutoCorrect des classes concernees (Boundary et CurveOnSurface) |
| 207 | /* |
| 208 | } else if (ent->IsKind(STANDARD_TYPE(IGESGeom_CurveOnSurface))) { |
| 209 | DeclareAndCast(IGESGeom_CurveOnSurface,cos,ent); // Curve UV |
| 210 | G.GetFromEntity (cos->CurveUV(),Standard_True,5); |
| 211 | } else if (ent->IsKind(STANDARD_TYPE(IGESGeom_Boundary))) { |
| 212 | DeclareAndCast(IGESGeom_Boundary,bnd,ent); // Curve UV |
| 213 | Standard_Integer nc = bnd->NbModelSpaceCurves(); |
| 214 | for (Standard_Integer ic = 1; ic <= nc; ic ++) { |
| 215 | Standard_Integer nuv = bnd->NbParameterCurves(ic); |
| 216 | for (Standard_Integer juv = 1; juv <= nuv; juv ++) |
| 217 | G.GetFromEntity(bnd->ParameterCurve(ic,juv),Standard_True,5); |
| 218 | } |
| 219 | */ |
| 220 | } |
| 221 | } |
| 222 | |
| 223 | // A present, on va appliquer tout cela "de force" |
| 224 | // Seule exception : des UseFlags non nuls deja en place sont laisses |
| 225 | |
| 226 | for (i = 1; i <= nb; i ++) { |
| 227 | Handle(IGESData_IGESEntity) ent = themodel->Entity(i); |
| 228 | Standard_Integer bl = ent->BlankStatus(); |
| 229 | Standard_Integer uf = ent->UseFlag(); |
| 230 | if (uf == 0) uf = G.Status(i); |
| 231 | Standard_Integer hy = ent->HierarchyStatus(); |
| 232 | //// cout<<" Ent.n0."<<i<<" Subord="<<subs.Value(i)<<" Use="<<uf<<endl; |
| 233 | ent->InitStatus(bl,subs.Value(i),uf,hy); |
| 234 | } |
| 235 | } |
| 236 | |
| 237 | |
| 238 | Standard_Boolean IGESData_BasicEditor::AutoCorrect |
| 239 | (const Handle(IGESData_IGESEntity)& ent) |
| 240 | { |
| 241 | if (themodel.IsNull()) return Standard_False; |
| 242 | Handle(IGESData_IGESEntity) bof, subent; |
| 243 | Handle(IGESData_LineFontEntity) linefont; |
| 244 | Handle(IGESData_LevelListEntity) levelist; |
| 245 | Handle(IGESData_ViewKindEntity) view; |
| 246 | Handle(IGESData_TransfEntity) transf; |
| 247 | Handle(IGESData_LabelDisplayEntity) labdisp; |
| 248 | Handle(IGESData_ColorEntity) color; |
| 249 | |
| 250 | Standard_Boolean done = Standard_False; |
| 251 | if (ent.IsNull()) return done; |
| 252 | // Corrections dans l entete (entites presentes) |
| 253 | // On ne verifie pas les items "Shared", presents de toute facon |
| 254 | // Entete : traite par DirChecker pour les cas standard |
| 255 | /* |
| 256 | linefont = ent->LineFont(); |
| 257 | if (!linefont.IsNull() && themodel->Number(linefont) == 0) { |
| 258 | linefont.Nullify(); |
| 259 | ent->InitLineFont(linefont,0); |
| 260 | done = Standard_True; |
| 261 | } |
| 262 | levelist = ent->LevelList(); |
| 263 | if (!levelist.IsNull() && themodel->Number(levelist) == 0) { |
| 264 | levelist.Nullify(); |
| 265 | ent->InitLevel(levelist,0); |
| 266 | done = Standard_True; |
| 267 | } |
| 268 | view = ent->View(); |
| 269 | if (!view.IsNull() && themodel->Number(view) == 0) { |
| 270 | view.Nullify(); |
| 271 | ent->InitView(view); |
| 272 | done = Standard_True; |
| 273 | } |
| 274 | transf = ent->Transf(); |
| 275 | if (!transf.IsNull() && themodel->Number(transf) == 0) { |
| 276 | transf.Nullify(); |
| 277 | ent->InitTransf(transf); |
| 278 | done = Standard_True; |
| 279 | } |
| 280 | labdisp = ent->LabelDisplay(); |
| 281 | if (!labdisp.IsNull() && themodel->Number(labdisp) == 0) { |
| 282 | labdisp.Nullify(); |
| 283 | ent->InitMisc (ent->Structure(),labdisp,ent->LineWeightNumber()); |
| 284 | done = Standard_True; |
| 285 | } |
| 286 | color = ent->Color(); |
| 287 | if (!color.IsNull() && themodel->Number(color) == 0) { |
| 288 | color.Nullify(); |
| 289 | ent->InitColor(color,0); |
| 290 | done = Standard_True; |
| 291 | } |
| 292 | */ |
| 293 | |
| 294 | // Corrections dans les Assocs (les Props restent attachees a l Entite) |
| 295 | Interface_EntityIterator iter = ent->Associativities(); |
| 296 | for (iter.Start(); iter.More(); iter.Next()) { |
| 297 | subent = GetCasted(IGESData_IGESEntity,iter.Value()); |
| 298 | if (!subent.IsNull() && themodel->Number(subent) == 0) |
| 299 | { subent->Dissociate(ent); done = Standard_True; } |
| 300 | } |
| 301 | |
| 302 | // Corrections specifiques |
| 303 | Handle(IGESData_GeneralModule) gmod; |
| 304 | Handle(IGESData_SpecificModule) smod; |
| 305 | Standard_Integer CN; |
| 306 | |
| 307 | if (theglib.Select (ent,gmod,CN)) { |
| 308 | IGESData_DirChecker DC = gmod->DirChecker(CN,ent); |
| 309 | done |= DC.Correct(ent); |
| 310 | } |
| 311 | if (theslib.Select (ent,smod,CN)) done |= smod->OwnCorrect (CN,ent); |
| 312 | |
| 313 | return done; |
| 314 | } |
| 315 | |
| 316 | |
| 317 | Standard_Integer IGESData_BasicEditor::AutoCorrectModel () |
| 318 | { |
| 319 | Standard_Integer res = 0; |
| 320 | Standard_Integer nb = themodel->NbEntities(); |
| 321 | for (Standard_Integer i = 1; i <= nb; i ++) { |
| 322 | if (AutoCorrect (themodel->Entity(i))) res ++; |
| 323 | } |
| 324 | return res; |
| 325 | } |
| 326 | |
| 327 | |
| 328 | |
| 329 | //======================================================================= |
| 330 | //function : UnitNameFlag |
| 331 | //purpose : |
| 332 | //======================================================================= |
| 333 | Standard_Integer IGESData_BasicEditor::UnitNameFlag (const Standard_CString name) |
| 334 | { |
| 335 | char* nam = (char *)&name[0]; |
| 336 | if (name[1] == 'H') { |
| 337 | nam = (char *)&name[2]; |
| 338 | } |
| 339 | if (!strcmp (nam,"INCH")) return 1; |
| 340 | if (!strcmp (nam,"IN")) return 1; |
| 341 | if (!strcmp (nam,"MM")) return 2; |
| 342 | if (!strcmp (nam,"FT")) return 4; |
| 343 | if (!strcmp (nam,"MI")) return 5; |
| 344 | if (!strcmp (nam,"M")) return 6; |
| 345 | if (!strcmp (nam,"KM")) return 7; |
| 346 | if (!strcmp (nam,"MIL")) return 8; |
| 347 | if (!strcmp (nam,"UM")) return 9; |
| 348 | if (!strcmp (nam,"CM")) return 10; |
| 349 | if (!strcmp (nam,"UIN")) return 11; |
| 350 | return 0; |
| 351 | } |
| 352 | |
| 353 | Standard_Real IGESData_BasicEditor::UnitFlagValue (const Standard_Integer flag) |
| 354 | { |
| 355 | switch (flag) { |
| 356 | case 1 : return 0.0254; |
| 357 | case 2 : return 0.001; |
| 358 | case 3 : return 1.; |
| 359 | case 4 : return 0.3048; |
| 360 | case 5 : return 1609.27; |
| 361 | case 6 : return 1.; |
| 362 | case 7 : return 1000.; |
| 363 | case 8 : return 0.0000254; |
| 364 | case 9 : return 0.000001; |
| 365 | case 10 : return 0.01; |
| 366 | case 11 : return 0.0000000254; |
| 367 | default : break; |
| 368 | } |
| 369 | return 0.; |
| 370 | } |
| 371 | |
| 372 | Standard_CString IGESData_BasicEditor::UnitFlagName (const Standard_Integer flag) |
| 373 | { |
| 374 | Standard_CString name = ""; |
| 375 | switch (flag) { |
| 376 | case 1 : name = "INCH"; break; |
| 377 | case 2 : name = "MM"; break; |
| 378 | case 4 : name = "FT"; break; |
| 379 | case 5 : name = "MI"; break; |
| 380 | case 6 : name = "M"; break; |
| 381 | case 7 : name = "KM"; break; |
| 382 | case 8 : name = "MIL"; break; |
| 383 | case 9 : name = "UM"; break; |
| 384 | case 10 : name = "CM"; break; |
| 385 | case 11 : name = "UIN"; break; |
| 386 | default : break; |
| 387 | } |
| 388 | return name; |
| 389 | } |
| 390 | |
| 391 | Standard_CString IGESData_BasicEditor::IGESVersionName (const Standard_Integer flag) |
| 392 | { |
| 393 | switch (flag) { |
| 394 | case 1 : return "1.0"; |
| 395 | case 2 : return "ANSI Y14.26M-1981"; |
| 396 | case 3 : return "2.0"; |
| 397 | case 4 : return "3.0"; |
| 398 | case 5 : return "ANSI Y14.26M-1987"; |
| 399 | case 6 : return "4.0"; |
| 400 | case 7 : return "ANSI Y14.26M-1989"; |
| 401 | case 8 : return "5.0"; |
| 402 | case 9 : return "5.1"; |
| 403 | case 10: return "5.2"; |
| 404 | case 11: return "5.3"; |
| 405 | default : break; |
| 406 | } |
| 407 | return ""; |
| 408 | } |
| 409 | |
| 410 | Standard_Integer IGESData_BasicEditor::IGESVersionMax () |
| 411 | { return 11; } |
| 412 | |
| 413 | Standard_CString IGESData_BasicEditor::DraftingName (const Standard_Integer flag) |
| 414 | { |
| 415 | switch (flag) { |
| 416 | case 0 : return "(None)"; |
| 417 | case 1 : return "ISO"; |
| 418 | case 2 : return "AFNOR"; |
| 419 | case 3 : return "ANSI"; |
| 420 | case 4 : return "BSI"; |
| 421 | case 5 : return "CSA"; |
| 422 | case 6 : return "DIN"; |
| 423 | case 7 : return "JIS"; |
| 424 | default : break; |
| 425 | } |
| 426 | return ""; |
| 427 | } |
| 428 | |
| 429 | Standard_Integer IGESData_BasicEditor::DraftingMax () |
| 430 | { return 7; } |