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