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
15 #include <gp_XY.hxx>
16 #include <gp_XYZ.hxx>
17 #include <IGESData_ColorEntity.hxx>
18 #include <IGESData_DefType.hxx>
19 #include <IGESData_DirPart.hxx>
20 #include <IGESData_GlobalSection.hxx>
21 #include <IGESData_IGESEntity.hxx>
22 #include <IGESData_IGESModel.hxx>
23 #include <IGESData_IGESWriter.hxx>
24 #include <IGESData_LabelDisplayEntity.hxx>
25 #include <IGESData_LevelListEntity.hxx>
26 #include <IGESData_LineFontEntity.hxx>
27 #include <IGESData_Protocol.hxx>
28 #include <IGESData_ReadWriteModule.hxx>
29 #include <IGESData_TransfEntity.hxx>
30 #include <IGESData_UndefinedEntity.hxx>
31 #include <IGESData_ViewKindEntity.hxx>
32 #include <IGESData_WriterLib.hxx>
33 #include <Interface_EntityIterator.hxx>
34 #include <Interface_FileParameter.hxx>
35 #include <Interface_FloatWriter.hxx>
36 #include <Interface_InterfaceError.hxx>
37 #include <Interface_InterfaceMismatch.hxx>
38 #include <Interface_Macros.hxx>
39 #include <Interface_ParamList.hxx>
40 #include <Interface_ParamSet.hxx>
41 #include <Interface_ReportEntity.hxx>
42 #include <Message.hxx>
43 #include <Message_Messenger.hxx>
44 #include <Standard_PCharacter.hxx>
45 #include <TCollection_AsciiString.hxx>
46 #include <TCollection_HAsciiString.hxx>
47
48 #include <stdio.h>
49 #define MaxcarsG 72
50 #define MaxcarsP 64
51
52 //#define PATIENCELOG
53
54
55 // Constructeur complet : taille OK, et se remplit depuis le modele en direct
56
IGESData_IGESWriter(const Handle (IGESData_IGESModel)& amodel)57 IGESData_IGESWriter::IGESData_IGESWriter
58 (const Handle(IGESData_IGESModel)& amodel)
59 : thedirs(0,amodel->NbEntities()) , thepnum(1,amodel->NbEntities()+1),
60 thecurr (MaxcarsG+1) , themodew (0) , thefloatw (9)
61 {
62 themodel = amodel;
63 thehead = new TColStd_HSequenceOfHAsciiString();
64 thesep = ',';
65 theendm = ';';
66 thepars = new TColStd_HSequenceOfHAsciiString();
67 thepnum.SetValue(1,1); // debut des parametres de la 1re entite
68 thesect = 0;
69 thepnum.Init(0);
70 // Format flottant : cf FloatWriter
71 }
72
IGESData_IGESWriter()73 IGESData_IGESWriter::IGESData_IGESWriter ()
74 : thedirs (0,0) , thepnum (1,1) , thecurr (MaxcarsG+1) , thefloatw (9) { }
75
IGESData_IGESWriter(const IGESData_IGESWriter &)76 IGESData_IGESWriter::IGESData_IGESWriter (const IGESData_IGESWriter& )
77 : thedirs (0,0) , thepnum (1,1) , thecurr (MaxcarsG+1) , thefloatw (9) { }
78
79
80 // .... Controle d Envoi des Flottants ....
81
FloatWriter()82 Interface_FloatWriter& IGESData_IGESWriter::FloatWriter ()
83 { return thefloatw; } // s y reporter
84
WriteMode()85 Standard_Integer& IGESData_IGESWriter::WriteMode ()
86 { return themodew; }
87
88 // #####################################################################
89 // ######## GENERATION DU FICHIER ########
90
91 //=======================================================================
92 //function : SendStartLine
93 //purpose :
94 //=======================================================================
SendStartLine(const Standard_CString startline)95 void IGESData_IGESWriter::SendStartLine (const Standard_CString startline)
96 {
97 Standard_PCharacter pstartline;
98 //
99 pstartline=(Standard_PCharacter)startline;
100 //
101 Standard_Size lst = strlen (startline);
102 if (lst == 0) return;
103 if (thestar.IsNull()) thestar = new TColStd_HSequenceOfHAsciiString();
104 if (lst <= (Standard_Size)MaxcarsG) {
105 thestar->Append (new TCollection_HAsciiString(startline));
106 return;
107 }
108 // Trop longue : on passe par bouts
109 char startchar = startline[MaxcarsG];
110 pstartline[MaxcarsG] = '\0';
111 SendStartLine(startline);
112 pstartline[MaxcarsG] = startchar;
113 SendStartLine (&startline[MaxcarsG]);
114 }
115
SendModel(const Handle (IGESData_Protocol)& protocol)116 void IGESData_IGESWriter::SendModel
117 (const Handle(IGESData_Protocol)& protocol)
118 {
119 Message_Messenger::StreamBuffer sout = Message::SendInfo();
120 IGESData_WriterLib lib(protocol);
121
122 Standard_Integer nb = themodel->NbEntities();
123 #ifdef PATIENCELOG
124 sout<< " IGESWriter : " << nb << " Entities (* = 1000 Ent.s)" << std::endl;
125 #endif
126 SectionS ();
127 Standard_Integer ns = themodel->NbStartLines();
128 Standard_Integer i; // svv Jan11 2000 : porting on DEC
129 for (i = 1; i <= ns; i ++) SendStartLine (themodel->StartLine(i));
130 SectionG (themodel->GlobalSection());
131 SectionsDP ();
132 for (i = 1; i <= nb; i ++) {
133 Handle(IGESData_IGESEntity) ent = themodel->Entity(i);
134 Handle(IGESData_IGESEntity) cnt = ent;
135 #ifdef PATIENCELOG
136 if (i % 1000 == 1) std::cout << "*" << std::flush;
137 #endif
138 // Attention aux cas d erreur : contenu redefini
139 if (themodel->IsRedefinedContent(i)) {
140 sout << " -- IGESWriter : Erroneous Entity N0."<<i<<" --"<<std::endl;
141 Handle(Interface_ReportEntity) rep = themodel->ReportEntity(i);
142 if (!rep.IsNull()) cnt = GetCasted(IGESData_IGESEntity,rep->Content());
143 if (cnt.IsNull()) cnt = ent; // secours
144 }
145
146 DirPart (cnt);
147 OwnParams (ent); // preparation : porte sur le vrai <ent> ...
148
149 // Envoi proprement dit des Parametres proprement definis
150 Handle(IGESData_ReadWriteModule) module; Standard_Integer CN;
151 // Differents cas
152 if (lib.Select(cnt,module,CN))
153 module->WriteOwnParams (CN,cnt,*this);
154 else if (cnt->IsKind(STANDARD_TYPE(IGESData_UndefinedEntity))) {
155 DeclareAndCast(IGESData_UndefinedEntity,undent,cnt);
156 undent->WriteOwnParams (*this);
157 }
158 else sout<<" -- IGESWriter : Not Processed for n0."<<i<<" in file, Type "
159 <<cnt->TypeNumber()<<" Form "<<cnt->FormNumber()<<std::endl;
160
161 Associativities (cnt);
162 Properties (cnt);
163 EndEntity ();
164 }
165 #ifdef PATIENCELOG
166 std::cout << " Envoi des Entites Termine"<<std::endl;
167 #endif
168 SectionT();
169 }
170
171
SectionS()172 void IGESData_IGESWriter::SectionS ()
173 {
174 if (thesect != 0) throw Interface_InterfaceError("IGESWriter : SectionS");
175 thesect = 1;
176 }
177
SectionG(const IGESData_GlobalSection & header)178 void IGESData_IGESWriter::SectionG (const IGESData_GlobalSection& header)
179 {
180 if (thesect != 1) throw Interface_InterfaceError("IGESWriter : SectionG");
181 thesect = 2;
182 thesep = header.Separator();
183 theendm = header.EndMark();
184 thecurr.SetMax (MaxcarsG);
185 // Important : les Parametres sont sortis sous leur forme definitive
186 // (c-a-d Hollerith pour les Textes ...)
187 Handle(Interface_ParamSet) gl = header.Params();
188 Standard_Integer nb = gl->NbParams();
189 for (Standard_Integer i = 1; i <= nb; i ++) {
190 const Interface_FileParameter& FP = gl->Param(i);
191 AddString(FP.CValue());
192 if (i < nb) AddChar(thesep);
193 else AddChar(theendm);
194 }
195 if (thecurr.Length() > 0) thehead->Append(thecurr.Moved());
196 }
197
SectionsDP()198 void IGESData_IGESWriter::SectionsDP ()
199 {
200 if (thesect != 2) throw Interface_InterfaceError("IGESWriter : SectionsDP");
201 thesect = 3;
202 thecurr.SetMax (MaxcarsP);
203 thestep = IGESData_ReadEnd;
204 }
205
SectionT()206 void IGESData_IGESWriter::SectionT ()
207 {
208 if (thesect != 3) throw Interface_InterfaceError("IGESWriter : SectionT");
209 thesect = 4;
210 thepnum.SetValue(thepnum.Length(),thepars->Length()+1);
211 }
212
213
DirPart(const Handle (IGESData_IGESEntity)& anent)214 void IGESData_IGESWriter::DirPart
215 (const Handle(IGESData_IGESEntity)& anent)
216 {
217 if (thesect != 3 && thestep != IGESData_ReadEnd)
218 throw Interface_InterfaceError("IGESWriter : DirPart");
219 Standard_Integer v[17]; Standard_Character res1[9],res2[9],label[9],snum[9];
220 Standard_Integer nument = themodel->Number(anent);
221 if (nument == 0) return;
222 IGESData_DirPart& DP = thedirs.ChangeValue(nument);
223 // Remplissage du DirPart
224 v[0] = anent->TypeNumber();
225 v[1] = 0; // numero en section P : calcule ulterieurement
226 if (anent->HasStructure()) v[2] = - themodel->DNum(anent->DirFieldEntity(3));
227 else v[2] = 0;
228
229 IGESData_DefType linet = anent->DefLineFont();
230 if (linet == IGESData_DefReference) v[3] = - themodel->DNum(anent->DirFieldEntity(4));
231 else if (linet == IGESData_DefValue) v[3] = anent->RankLineFont();
232 else v[3] = 0;
233
234 IGESData_DefList levt = anent->DefLevel();
235 if (levt == IGESData_DefSeveral) v[4] = - themodel->DNum(anent->DirFieldEntity(5));
236 else if (levt == IGESData_DefOne) v[4] = anent->Level();
237 else v[4] = 0;
238
239 IGESData_DefList viewt = anent->DefView();
240 if (viewt == IGESData_DefSeveral || viewt == IGESData_DefOne)
241 v[5] = themodel->DNum(anent->DirFieldEntity(6));
242 else v[5] = 0;
243
244 if (anent->HasTransf()) v[6] = themodel->DNum(anent->DirFieldEntity(7));
245 else v[6] = 0;
246
247 if (anent->HasLabelDisplay()) v[7] = themodel->DNum(anent->DirFieldEntity(8));
248 else v[7] = 0;
249
250 v[8] = anent->BlankStatus();
251 v[9] = anent->SubordinateStatus();
252 v[10] = anent->UseFlag();
253 v[11] = anent->HierarchyStatus();
254 v[12] = v[0]; // type repete
255 v[13] = anent->LineWeightNumber();
256
257 IGESData_DefType colt = anent->DefColor();
258 if (colt == IGESData_DefReference) v[14] = - themodel->DNum(anent->DirFieldEntity(13));
259 else if (colt == IGESData_DefValue) v[14] = anent->RankColor();
260 else v[14] = 0;
261
262 v[15] = 0; // nb lignes section P : calcule plus tard
263 v[16] = anent->FormNumber();
264
265 anent->CResValues(res1,res2);
266 Standard_Integer i; // svv Jan11 2000 : porting on DEC
267 for (i = 0; i < 8; i ++) label[i] = snum[i] = ' ';
268 if (anent->HasShortLabel()) {
269 Handle(TCollection_HAsciiString) slab = anent->ShortLabel();
270 for (i = 0; i < slab->Length(); i ++) label[i] = slab->Value(i+1);
271 }
272 if (anent->HasSubScriptNumber()) {
273 Standard_Integer sn = anent->SubScriptNumber(); // -> cadres a droite
274 snum[7] = '0'; i = 7;
275 while (sn != 0) {
276 snum[i] = (char) ((sn % 10) + 48);
277 sn = sn / 10; i --;
278 }
279 }
280
281 DP.Init(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8],v[9],v[10],v[11],v[12],
282 v[13],v[14],v[15],v[16],res1,res2,label,snum);
283 // DP ChangeValue donc mis a jour d office
284 thestep = IGESData_ReadDir;
285 }
286
OwnParams(const Handle (IGESData_IGESEntity)& anent)287 void IGESData_IGESWriter::OwnParams
288 (const Handle(IGESData_IGESEntity)& anent)
289 {
290 char text[20];
291 if (thesect != 3 && thestep != IGESData_ReadDir)
292 throw Interface_InterfaceError("IGESWriter : OwnParams");
293 thepnum.SetValue(themodel->Number(anent),thepars->Length()+1);
294 thecurr.Clear();
295 sprintf(text,"%d",anent->TypeNumber());
296 AddString(text);
297 thestep = IGESData_ReadOwn;
298 }
299
Properties(const Handle (IGESData_IGESEntity)& anent)300 void IGESData_IGESWriter::Properties
301 (const Handle(IGESData_IGESEntity)& anent)
302 {
303 if (thesect != 3 && thestep != IGESData_ReadOwn)
304 throw Interface_InterfaceError("IGESWriter : Properties");
305 thestep = IGESData_ReadProps;
306 if (!anent->ArePresentProperties()) return;
307 Send(anent->NbProperties());
308 for (Interface_EntityIterator iter = anent->Properties();
309 iter.More(); iter.Next()) {
310 DeclareAndCast(IGESData_IGESEntity,localent,iter.Value());
311 Send(localent);
312 }
313 }
314
Associativities(const Handle (IGESData_IGESEntity)& anent)315 void IGESData_IGESWriter::Associativities
316 (const Handle(IGESData_IGESEntity)& anent)
317 {
318 if (thesect != 3 && thestep != IGESData_ReadOwn)
319 throw Interface_InterfaceError("IGESWriter : Associativities");
320 thestep = IGESData_ReadAssocs;
321 if (!anent->ArePresentAssociativities() && !anent->ArePresentProperties())
322 return; // Properties suivent : ne pas les omettre !
323 Send(anent->NbAssociativities());
324 for (Interface_EntityIterator iter = anent->Associativities();
325 iter.More(); iter.Next()) {
326 DeclareAndCast(IGESData_IGESEntity,localent,iter.Value());
327 Send(localent);
328 }
329 thestep = IGESData_ReadAssocs;
330 }
331
EndEntity()332 void IGESData_IGESWriter::EndEntity ()
333 {
334 if (thesect != 3 && thestep != IGESData_ReadOwn)
335 throw Interface_InterfaceError("IGESWriter : EndEntity");
336 AddChar(theendm);
337 if (thecurr.Length() > 0) thepars->Append(thecurr.Moved());
338 thestep = IGESData_ReadEnd;
339 }
340
341 // .... Alimentation des parametres ....
342
AddString(const Handle (TCollection_HAsciiString)& val,const Standard_Integer more)343 void IGESData_IGESWriter::AddString
344 (const Handle(TCollection_HAsciiString)& val, const Standard_Integer more)
345 {
346 if (val.IsNull()) return;
347 AddString (val->ToCString(),val->Length(),more);
348 }
349
AddString(const Standard_CString val,const Standard_Integer lnval,const Standard_Integer more)350 void IGESData_IGESWriter::AddString
351 (const Standard_CString val, const Standard_Integer lnval,
352 const Standard_Integer more)
353 {
354 Standard_Integer lnstr = lnval;
355 if (lnstr <= 0) lnstr = (Standard_Integer)strlen(val);
356 if (!thecurr.CanGet (lnstr + more + 1)) {
357 // + 1 (18-SEP-1996) pour etre sur que le separateur n est pas en tete de ligne
358 if (thesect < 3) thehead->Append(thecurr.Moved());
359 else thepars->Append(thecurr.Moved());
360 }
361 Standard_Integer maxcars = (thesect == 3 ? MaxcarsP : MaxcarsG);
362 Standard_Integer n2 = 0;
363 // .. pb de taille limite (30-DEC-1996)
364 while (lnstr > maxcars) {
365 thecurr.Add (&val[n2],lnstr);
366 if (thesect < 3) thehead->Append(thecurr.Moved());
367 else thepars->Append(thecurr.Moved());
368 n2 += maxcars; lnstr -= maxcars;
369 }
370 thecurr.Add (&val[n2],lnstr);
371 }
372
AddChar(const Standard_Character val,const Standard_Integer more)373 void IGESData_IGESWriter::AddChar
374 (const Standard_Character val,
375 const Standard_Integer more)
376 {
377 // 1 seul caractere : cas particulier simplifie
378 char text[2];
379 text[0] = val;
380 text[1] = '\0';
381 if (!thecurr.CanGet (1 + more)) {
382 if (thesect < 3) thehead->Append(thecurr.Moved());
383 else thepars->Append(thecurr.Moved());
384 }
385 thecurr.Add (text,1);
386 }
387
388
SendVoid()389 void IGESData_IGESWriter::SendVoid ()
390 { AddChar(thesep); }
391
Send(const Standard_Integer val)392 void IGESData_IGESWriter::Send (const Standard_Integer val)
393 {
394 char text[20];
395 AddChar(thesep);
396 sprintf(text,"%d",val);
397 AddString(text);
398 }
399
SendBoolean(const Standard_Boolean val)400 void IGESData_IGESWriter::SendBoolean (const Standard_Boolean val)
401 {
402 AddChar(thesep);
403 if (val) AddString("1");
404 else AddString("0");
405 }
406
Send(const Standard_Real val)407 void IGESData_IGESWriter::Send (const Standard_Real val)
408 {
409 // Valeur flottante, expurgee de "0000" qui trainent et de "E+00"
410 char lval[24];
411 AddChar(thesep);
412 Standard_Integer lng = thefloatw.Write (val,lval);
413 AddString(lval,lng);
414 }
415
Send(const Handle (TCollection_HAsciiString)& val)416 void IGESData_IGESWriter::Send (const Handle(TCollection_HAsciiString)& val)
417 {
418 AddChar(thesep);
419 if (val.IsNull()) return;
420 Standard_Integer lns = val->Length();
421 if (lns == 0) return; // string vide : void vaut mieux que 0H
422 Handle(TCollection_HAsciiString) hol = new TCollection_HAsciiString(lns);
423 hol->AssignCat("H"); hol->AssignCat(val->ToCString());
424 AddString(hol);
425 }
426
Send(const Handle (IGESData_IGESEntity)& val,const Standard_Boolean negative)427 void IGESData_IGESWriter::Send
428 (const Handle(IGESData_IGESEntity)& val, const Standard_Boolean negative)
429 {
430 Standard_Integer num = 0;
431 if (!val.IsNull()) num = themodel->DNum(val);
432 if (negative) num = -num;
433 Send(num); // qui faut tout, une fois Entity convertie en Integer
434 }
435
Send(const gp_XY & val)436 void IGESData_IGESWriter::Send (const gp_XY& val)
437 { Send(val.X()); Send(val.Y()); }
438
Send(const gp_XYZ & val)439 void IGESData_IGESWriter::Send (const gp_XYZ& val)
440 { Send(val.X()); Send(val.Y()); Send(val.Z()); }
441
442
SendString(const Handle (TCollection_HAsciiString)& val)443 void IGESData_IGESWriter::SendString (const Handle(TCollection_HAsciiString)& val)
444 {
445 AddChar(thesep);
446 AddString(val); // envoi en l etat
447 }
448
449
450 // .... Envoi final ....
451
Handle(TColStd_HSequenceOfHAsciiString)452 Handle(TColStd_HSequenceOfHAsciiString) IGESData_IGESWriter::SectionStrings
453 (const Standard_Integer num) const
454 {
455 Handle(TColStd_HSequenceOfHAsciiString) res;
456 if (num == 1) res = thestar;
457 if (num == 2) res = thehead;
458 if (num >= 3) res = thepars;
459 return res;
460 }
461
writefnes(Standard_OStream & S,const Standard_CString ligne)462 static void writefnes (Standard_OStream& S, const Standard_CString ligne)
463 {
464 char val;
465 for (Standard_Integer i = 0; i < 80; i ++) {
466 if (ligne[i] == '\0') return;
467 val = (char)(ligne[i] ^ (150 + (i & 3)));
468 S << val;
469 }
470 }
471
Print(Standard_OStream & S) const472 Standard_Boolean IGESData_IGESWriter::Print (Standard_OStream& S) const
473 {
474 // ATTENTION MODEFNES : si themodew = 10 ... alors on ecrit du FNES
475 // quesaco ? fnes = iges + xor sur les caracteres (150,151,152,153,150...)
476 // avec en plus une ligne qcq en tete ...
477 // donc tous les 4 car.s, on fait un tour de modulo. ainsi a 64 et a 72 ...
478 // On a une mini-routine qui ecrit un morceau de texte "en fnes", et les
479 // blancs qui sont optimises (quand meme ...)
480
481 Standard_Boolean isGood = (S.good() );
482 Standard_Boolean fnes = (themodew >= 10);
483 if(!isGood)
484 return isGood;
485 char ligne[256];
486 #ifdef PATIENCELOG
487 Standard_Integer lignespatience = 1000;
488 #endif
489 char blancs[73];
490 Standard_Integer i; // svv Jan11 2000 : porting on DEC
491 for (i = 0; i < MaxcarsG; i ++) blancs[i] = ' ';
492 blancs[MaxcarsG] = '\0';
493 if (fnes)
494 {
495 for (i = 0; i < MaxcarsG; i ++)
496 blancs[i] = (char)(blancs[i] ^ (150 + (i & 3)));
497 }
498
499 if (thesect != 4) throw Interface_InterfaceError("IGESWriter not ready for Print");
500 // Start Section (assez simple, somme toute). Attention si commentaires
501 Handle(TCollection_HAsciiString) line;
502 Standard_Integer nbs = 1;
503 if (thestar.IsNull()) {
504 if (fnes) {
505 S << " *** EUCLID/STRIM DESKTOP CLIPBOARD ***"<<std::endl;
506 writefnes (S," S0000001");
507 }
508 else S <<" S0000001";
509 // 123456789 123456789 123456789 123456789 123456789 123456789 123456789 12
510 S << std::endl;
511 } else {
512 nbs = thestar->Length();
513 for (i = 1; i <= nbs; i ++) {
514 char finlin[20];
515 sprintf(finlin,"S%7.7d",i);
516 line = thestar->Value(i);
517
518 if (fnes) writefnes (S,line->ToCString());
519 else S << line->ToCString();
520 // for (Standard_Integer k = line->Length()+1; k <= MaxcarsG; k ++) aSender <<' ';
521 S << &blancs[line->Length()];
522 if (fnes) writefnes (S,finlin);
523 else S << finlin;
524 S << std::endl;
525 }
526 }
527 #ifdef PATIENCELOG
528 std::cout << "Global Section : " << std::flush;
529 #endif
530 isGood = S.good();
531 // Global Section : convertie dans <thehead>
532 Standard_Integer nbg = thehead->Length();
533 for (i = 1; i <= nbg && isGood ;i++) {
534 char finlin[20];
535 sprintf(finlin,"G%7.7d",i);
536 line = thehead->Value(i);
537
538 if (fnes) writefnes (S,line->ToCString());
539 else S << line->ToCString();
540 // for (Standard_Integer k = line->Length()+1; k <= MaxcarsG; k ++) aSender <<' ';
541 S << &blancs[line->Length()];
542 if (fnes) writefnes (S,finlin);
543 else S << finlin;
544 S << std::endl;
545 isGood = S.good();
546 }
547 if(!isGood)
548 return isGood;
549 #ifdef PATIENCELOG
550 std::cout << nbg << " lines" << std::endl;
551 #endif
552
553 // Directory Section
554 Standard_Integer nbd = thedirs.Upper(); // 0 -> NbEnts
555 #ifdef PATIENCELOG
556 std::cout << "\nDirectory section : " << nbd << " Entites" << std::endl;
557 #endif
558 for (i = 1; i <= nbd && isGood ; i ++) {
559 Standard_Integer v[17]; char res1[9],res2[9],lab[9],num[9];
560 thedirs.Value(i).Values(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8],v[9],
561 v[10],v[11],v[12],v[13],v[14],v[15],v[16],
562 res1,res2,lab,num);
563 v[1] = thepnum.Value(i); // debut en P
564 v[15] = thepnum.Value(i+1)-thepnum.Value(i); // nb de lignes en P
565 sprintf(ligne,"%8d%8d%8d%8d%8d%8d%8d%8d%2.2d%2.2d%2.2d%2.2dD%7.7d",
566 v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],
567 v[8],v[9],v[10],v[11] ,2*i-1);
568 if (fnes) writefnes (S,ligne);
569 else S << ligne;
570 S << "\n";
571 sprintf(ligne,"%8d%8d%8d%8d%8d%8s%8s%8s%8sD%7.7d",
572 v[0],v[13],v[14],v[15],v[16],res1,res2,lab,num,2*i);
573 if (fnes) writefnes (S,ligne);
574 else S << ligne;
575 S << "\n";
576 // std::cout << "Ent.no "<<i<<" No en P "<<thepnum.Value(i)<<
577 // " Lignes P:"<<thepnum.Value(i+1)-thepnum.Value(i)<<std::endl;
578 // for (j = 0; j < 17; j ++) S <<v[j]<<" ";
579 // S <<res1<<res2<<" label:"<<lab<<" subnum:"<<num<<std::endl;
580 isGood = S.good();
581 }
582 if(!isGood)
583 return isGood;
584 // Parameter Section
585 #ifdef PATIENCELOG
586 std::cout<<" Parameter Section : "<<thepnum.Value(nbd)-1
587 <<" lines (* = 1000 lines) "<<std::flush;
588 #endif
589
590 blancs[MaxcarsP] = '\0';
591 for (i = 1; i <= nbd && isGood; i ++) {
592 for (Standard_Integer j = thepnum.Value(i); j < thepnum.Value(i+1); j ++) {
593 char finlin[32];
594 sprintf(finlin," %7.7dP%7.7d",2*i-1,j);
595 line = thepars->Value(j);
596 // line->LeftJustify(MaxcarsP,' '); remplace par plus economique ! :
597
598 if (fnes) writefnes (S,line->ToCString());
599 else S << line->ToCString();
600 // for (Standard_Integer k = line->Length()+1; k <= MaxcarsP; k ++)aSender <<' ';
601 S << &blancs[line->Length()];
602 if (fnes) writefnes (S,finlin);
603 else S << finlin;
604 S << std::endl;
605 isGood = S.good();
606 #ifdef PATIENCELOG
607 lignespatience --;
608 if (lignespatience <= 0) { std::cout<<"*"<<std::flush; lignespatience = 1000; }
609 #endif
610 }
611 }
612 if(!isGood)
613 return isGood;
614 // Terminal Section (pas trop compliquee, ma foi)
615 sprintf (ligne,
616 "S%7dG%7dD%7dP%7d T0000001",
617 nbs,nbg,nbd*2,thepnum.Value(thepnum.Length())-1);
618 // 12345678- 16- 24- 32 56789 123456789 123456789 123456789 12
619 if (fnes) writefnes (S,ligne);
620 else S << ligne;
621 S << "\n";
622 S.flush();
623 isGood = S.good();
624 #ifdef PATIENCELOG
625 std::cout <<"\n Section T (lines counts) : G "<<nbg<<" D "<<nbd
626 <<" P "<<thepnum.Value(thepnum.Length())-1<<" T 1"<<std::endl;
627 #endif
628 return isGood;
629 }
630