00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "nel/ligo/primitive.h"
00027 #include "nel/misc/i_xml.h"
00028
00029 using namespace NLMISC;
00030 using namespace std;
00031
00032 #define NLLIGO_PRIMITVE_VERSION 0
00033
00034 namespace NLLIGO
00035 {
00036
00037
00038
00039
00040
00041 void Error (const char *filename, const char *format, ...)
00042 {
00043 va_list args;
00044 va_start( args, format );
00045 char buffer[1024];
00046 sint ret = vsnprintf( buffer, 1024, format, args );
00047 va_end( args );
00048
00049 nlwarning ("In File (%s) %s", filename, buffer);
00050 }
00051
00052
00053
00054 void XMLError (xmlNodePtr xmlNode, const char *filename, const char *format, ... )
00055 {
00056 va_list args;
00057 va_start( args, format );
00058 char buffer[1024];
00059 sint ret = vsnprintf( buffer, 1024, format, args );
00060 va_end( args );
00061
00062 Error (filename, "node (%s), line (%d) : %s", xmlNode->name, (int)xmlNode->content, buffer);
00063 }
00064
00065
00066
00067
00068 xmlNodePtr GetFirstChildNode (xmlNodePtr xmlNode, const char *filename, const char *childName)
00069 {
00070
00071 xmlNodePtr result;
00072 if ((result = CIXml::getFirstChildNode (xmlNode, childName)))
00073 {
00074 return result;
00075 }
00076 else
00077 {
00078
00079 XMLError (xmlNode, filename, "Can't find XML node named (%s)", childName);
00080 return NULL;
00081 }
00082 }
00083
00084
00085
00086 bool GetPropertyString (string &result, const char *filename, xmlNodePtr xmlNode, const char *propName)
00087 {
00088
00089 if (!CIXml::getPropertyString (result, xmlNode, propName))
00090 {
00091
00092 XMLError (xmlNode, filename, "Can't find XML node property (%s)", propName);
00093 return false;
00094 }
00095 return true;
00096 }
00097
00098
00099
00100 bool ReadFloat (const char *propName, float &result, const char *filename, xmlNodePtr xmlNode)
00101 {
00102 string value;
00103 if (GetPropertyString (value, filename, xmlNode, propName))
00104 {
00105 result = (float)atof (value.c_str ());
00106 return true;
00107 }
00108 return false;
00109 }
00110
00111
00112
00113 bool ReadVector (CPrimVector &point, const char *filename, xmlNodePtr xmlNode)
00114 {
00115 CPrimVector pos;
00116 if (ReadFloat ("X", pos.x, filename, xmlNode))
00117 {
00118 if (ReadFloat ("Y", pos.y, filename, xmlNode))
00119 {
00120 if (ReadFloat ("Z", pos.z, filename, xmlNode))
00121 {
00122 pos.Selected = false;
00123 string result;
00124 if (CIXml::getPropertyString (result, xmlNode, "SELECTED"))
00125 {
00126 if (result == "true")
00127 pos.Selected = true;
00128 }
00129 point = pos;
00130 return true;
00131 }
00132 }
00133 }
00134 return false;
00135 }
00136
00137
00138
00139 void WriteVector (const CPrimVector &point, xmlNodePtr xmlNode)
00140 {
00141
00142 xmlSetProp (xmlNode, (const xmlChar*)"X", (const xmlChar*)(toString (point.x).c_str ()));
00143 xmlSetProp (xmlNode, (const xmlChar*)"Y", (const xmlChar*)(toString (point.y).c_str ()));
00144 xmlSetProp (xmlNode, (const xmlChar*)"Z", (const xmlChar*)(toString (point.z).c_str ()));
00145 if (point.Selected)
00146 xmlSetProp (xmlNode, (const xmlChar*)"SELECTED", (const xmlChar*)"true");
00147 }
00148
00149
00150
00151 void WriteFloat (const char *propName, float value, xmlNodePtr xmlNode)
00152 {
00153
00154 xmlSetProp (xmlNode, (const xmlChar*)propName, (const xmlChar*)(toString (value).c_str ()));
00155 }
00156
00157
00158
00159 bool GetNodeString (string &result, const char *filename, xmlNodePtr xmlNode, const char *nodeName)
00160 {
00161
00162 xmlNodePtr node = CIXml::getFirstChildNode (xmlNode, nodeName);
00163 if (!node)
00164 {
00165 XMLError (xmlNode, filename, "Can't find XML node named (%s)", nodeName);
00166 return false;
00167 }
00168
00169
00170 if (!CIXml::getContentString (result, node))
00171 {
00172 XMLError (xmlNode, filename, "Can't find any text in the node named (%s)", nodeName);
00173 return false;
00174 }
00175
00176 return true;
00177 }
00178
00179
00180
00181 bool GetContentString (string &result, const char *filename, xmlNodePtr xmlNode)
00182 {
00183
00184 if (!CIXml::getContentString (result, xmlNode))
00185 {
00186 XMLError (xmlNode, filename, "Can't find any text in the node");
00187 return false;
00188 }
00189
00190 return true;
00191 }
00192
00193
00194
00195
00196
00197 CPropertyString::CPropertyString (const char *str)
00198 {
00199 String = str;
00200 }
00201
00202
00203
00204
00205
00206 CPropertyStringArray::CPropertyStringArray (const std::vector<std::string> &stringArray)
00207 {
00208 StringArray = stringArray;
00209 }
00210
00211
00212
00213 void CPrimPoint::serial (IStream &f)
00214 {
00215 f.xmlPushBegin ("POINT");
00216
00217 f.xmlSetAttrib ("NAME");
00218 f.serial (Name);
00219 f.xmlSetAttrib ("LAYER");
00220 f.serial (Layer);
00221 f.xmlPushEnd ();
00222
00223 f.serial (Point);
00224
00225 if (f.isReading ())
00226 {
00227 Angle = 0;
00228 }
00229
00230 f.xmlPop ();
00231 }
00232
00233
00234 void CPrimPath::serial (IStream &f)
00235 {
00236 f.xmlPushBegin ("PATH");
00237
00238 f.xmlSetAttrib ("NAME");
00239 f.serial (Name);
00240 f.xmlSetAttrib ("LAYER");
00241 f.serial (Layer);
00242 f.xmlPushEnd ();
00243
00244 f.serialCont (VPoints);
00245
00246 f.xmlPop ();
00247 }
00248
00249
00250
00251 bool CPrimZone::contains (const NLMISC::CVector &v, const std::vector<CPrimVector> &points)
00252 {
00253 uint32 i;
00254 CVector vMin, vMax;
00255
00256
00257 if (points.size() < 3)
00258 return false;
00259
00260
00261 vMax = vMin = points[0];
00262 for (i = 0; i < points.size(); ++i)
00263 {
00264 if (vMin.x > points[i].x)
00265 vMin.x = points[i].x;
00266 if (vMin.y > points[i].y)
00267 vMin.y = points[i].y;
00268
00269 if (vMax.x < points[i].x)
00270 vMax.x = points[i].x;
00271 if (vMax.y < points[i].y)
00272 vMax.y = points[i].y;
00273 }
00274
00275 if ((v.x < vMin.x) || (v.y < vMin.y) || (v.x > vMax.x) || (v.y > vMax.y))
00276 return false;
00277
00278 uint32 nNbIntersection = 0;
00279 for (i = 0; i < points.size(); ++i)
00280 {
00281 const CVector &p1 = points[i];
00282 const CVector &p2 = points[(i+1)%points.size()];
00283
00284 if (((p1.y-v.y) < 0.0)&&((p2.y-v.y) < 0.0))
00285 continue;
00286 if (((p1.y-v.y) > 0.0)&&((p2.y-v.y) > 0.0))
00287 continue;
00288 float xinter = p1.x + (p2.x-p1.x) * ((v.y-p1.y)/(p2.y-p1.y));
00289 if (xinter > v.x)
00290 ++nNbIntersection;
00291 }
00292 if ((nNbIntersection&1) == 1)
00293 return true;
00294 else
00295 return false;
00296 }
00297
00298
00299
00300 bool CPrimZone::contains (const NLMISC::CVector &v, const std::vector<NLMISC::CVector> &points)
00301 {
00302 uint32 i;
00303 CVector vMin, vMax;
00304
00305
00306 if (points.size() < 3)
00307 return false;
00308
00309
00310 vMax = vMin = points[0];
00311 for (i = 0; i < points.size(); ++i)
00312 {
00313 if (vMin.x > points[i].x)
00314 vMin.x = points[i].x;
00315 if (vMin.y > points[i].y)
00316 vMin.y = points[i].y;
00317
00318 if (vMax.x < points[i].x)
00319 vMax.x = points[i].x;
00320 if (vMax.y < points[i].y)
00321 vMax.y = points[i].y;
00322 }
00323
00324 if ((v.x < vMin.x) || (v.y < vMin.y) || (v.x > vMax.x) || (v.y > vMax.y))
00325 return false;
00326
00327 uint32 nNbIntersection = 0;
00328 for (i = 0; i < points.size(); ++i)
00329 {
00330 const CVector &p1 = points[i];
00331 const CVector &p2 = points[(i+1)%points.size()];
00332
00333 if (((p1.y-v.y) < 0.0)&&((p2.y-v.y) < 0.0))
00334 continue;
00335 if (((p1.y-v.y) > 0.0)&&((p2.y-v.y) > 0.0))
00336 continue;
00337 float xinter = p1.x + (p2.x-p1.x) * ((v.y-p1.y)/(p2.y-p1.y));
00338 if (xinter > v.x)
00339 ++nNbIntersection;
00340 }
00341 if ((nNbIntersection&1) == 1)
00342 return true;
00343 else
00344 return false;
00345 }
00346
00347
00348
00349
00350
00351 bool CPrimNode::read (xmlNodePtr xmlNode, const char *filename, uint version)
00352 {
00353 return IPrimitive::read (xmlNode, filename, version);
00354 }
00355
00356
00357
00358 void CPrimNode::write (xmlNodePtr xmlNode, const char *filename) const
00359 {
00360
00361 xmlSetProp (xmlNode, (const xmlChar*)"TYPE", (const xmlChar*)"node");
00362
00363 IPrimitive::write (xmlNode, filename);
00364 }
00365
00366
00367
00368 uint CPrimNode::getNumVector () const
00369 {
00370 return 0;
00371 }
00372
00373
00374
00375 const CPrimVector *CPrimNode::getPrimVector () const
00376 {
00377 return NULL;
00378 }
00379
00380
00381
00382 CPrimVector *CPrimNode::getPrimVector ()
00383 {
00384 return NULL;
00385 }
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423 uint CPrimPoint::getNumVector () const
00424 {
00425 return 1;
00426 }
00427
00428
00429
00430 const CPrimVector *CPrimPoint::getPrimVector () const
00431 {
00432 return &Point;
00433 }
00434
00435
00436
00437 CPrimVector *CPrimPoint::getPrimVector ()
00438 {
00439 return &Point;
00440 }
00441
00442
00443
00444 bool CPrimPoint::read (xmlNodePtr xmlNode, const char *filename, uint version)
00445 {
00446
00447 xmlNodePtr ptNode = GetFirstChildNode (xmlNode, filename, "PT");
00448 if (ptNode)
00449 {
00450
00451 if (!ReadVector (Point, filename, ptNode))
00452 return false;
00453
00454 ptNode = GetFirstChildNode (xmlNode, filename, "ANGLE");
00455 if (ptNode)
00456 {
00457
00458 if (!ReadFloat ("VALUE", Angle, filename, ptNode))
00459 return false;
00460 }
00461 else
00462 Angle = 0;
00463 }
00464 else
00465 {
00466 return false;
00467 }
00468
00469 return IPrimitive::read (xmlNode, filename, version);
00470 }
00471
00472
00473
00474 void CPrimPoint::write (xmlNodePtr xmlNode, const char *filename) const
00475 {
00476
00477 xmlSetProp (xmlNode, (const xmlChar*)"TYPE", (const xmlChar*)"point");
00478
00479
00480 xmlNodePtr ptNode = xmlNewChild ( xmlNode, NULL, (const xmlChar*)"PT", NULL);
00481 WriteVector (Point, ptNode);
00482
00483
00484 if (Angle != 0)
00485 {
00486 xmlNodePtr ptNode = xmlNewChild ( xmlNode, NULL, (const xmlChar*)"ANGLE", NULL);
00487 WriteFloat ("VALUE", Angle, ptNode);
00488 }
00489
00490 IPrimitive::write (xmlNode, filename);
00491 }
00492
00493
00494
00495
00496
00497 uint CPrimPath::getNumVector () const
00498 {
00499 return VPoints.size ();
00500 }
00501
00502
00503
00504 const CPrimVector *CPrimPath::getPrimVector () const
00505 {
00506 return &(VPoints[0]);
00507 }
00508
00509
00510
00511 CPrimVector *CPrimPath::getPrimVector ()
00512 {
00513 return &(VPoints[0]);
00514 }
00515
00516
00517
00518 bool CPrimPath::read (xmlNodePtr xmlNode, const char *filename, uint version)
00519 {
00520
00521 VPoints.clear ();
00522 VPoints.reserve (CIXml::countChildren (xmlNode, "PT"));
00523 xmlNodePtr ptNode = CIXml::getFirstChildNode (xmlNode, "PT");
00524 if (ptNode)
00525 {
00526 do
00527 {
00528
00529 VPoints.push_back (CPrimVector ());
00530 if (!ReadVector (VPoints.back (), filename, ptNode))
00531 return false;
00532 }
00533 while ((ptNode = CIXml::getNextChildNode (ptNode, "PT")));
00534 }
00535
00536 return IPrimitive::read (xmlNode, filename, version);
00537 }
00538
00539
00540
00541 void CPrimPath::write (xmlNodePtr xmlNode, const char *filename) const
00542 {
00543
00544 xmlSetProp (xmlNode, (const xmlChar*)"TYPE", (const xmlChar*)"path");
00545
00546
00547 for (uint i=0; i<VPoints.size (); i++)
00548 {
00549 xmlNodePtr ptNode = xmlNewChild ( xmlNode, NULL, (const xmlChar*)"PT", NULL);
00550 WriteVector (VPoints[i], ptNode);
00551 }
00552
00553 IPrimitive::write (xmlNode, filename);
00554 }
00555
00556
00557
00558
00559
00560 uint CPrimZone::getNumVector () const
00561 {
00562 return VPoints.size ();
00563 }
00564
00565
00566
00567 const CPrimVector *CPrimZone::getPrimVector () const
00568 {
00569 return &(VPoints[0]);
00570 }
00571
00572
00573
00574 CPrimVector *CPrimZone::getPrimVector ()
00575 {
00576 return &(VPoints[0]);
00577 }
00578
00579
00580
00581 bool CPrimZone::read (xmlNodePtr xmlNode, const char *filename, uint version)
00582 {
00583
00584 VPoints.clear ();
00585 VPoints.reserve (CIXml::countChildren (xmlNode, "PT"));
00586 xmlNodePtr ptNode = CIXml::getFirstChildNode (xmlNode, "PT");
00587 if (ptNode)
00588 {
00589 do
00590 {
00591
00592 VPoints.push_back (CPrimVector ());
00593 if (!ReadVector (VPoints.back (), filename, ptNode))
00594 return false;
00595 }
00596 while ((ptNode = CIXml::getNextChildNode (ptNode, "PT")));
00597 }
00598
00599 return IPrimitive::read (xmlNode, filename, version);
00600 }
00601
00602
00603
00604 void CPrimZone::write (xmlNodePtr xmlNode, const char *filename) const
00605 {
00606
00607 xmlSetProp (xmlNode, (const xmlChar*)"TYPE", (const xmlChar*)"zone");
00608
00609
00610 for (uint i=0; i<VPoints.size (); i++)
00611 {
00612 xmlNodePtr ptNode = xmlNewChild ( xmlNode, NULL, (const xmlChar*)"PT", NULL);
00613 WriteVector (VPoints[i], ptNode);
00614 }
00615
00616 IPrimitive::write (xmlNode, filename);
00617 }
00618
00619
00620
00621 bool CPrimZone::contains (const NLMISC::CVector &v, const std::vector<CPrimVector> &points, float &distance, NLMISC::CVector &nearPos, bool isPath)
00622 {
00623 uint32 i;
00624 CVector vMin, vMax;
00625 float nearest = FLT_MAX;
00626 CVector pos;
00627
00628
00629 if (points.size() < 3 || isPath)
00630 {
00631
00632 if (points.size() == 1)
00633 {
00634 distance = (points[0] - v).norm();
00635 nearPos = points[0];
00636 }
00637 else if (points.size() == 2)
00638 {
00639 distance = getSegmentDist(v, points[0], points[1], nearPos);
00640 }
00641 else
00642 {
00643
00644 for (i = 0; i < points.size()-1; ++i)
00645 {
00646 const CVector &p1 = points[i];
00647 const CVector &p2 = points[i+1];
00648
00649 float dist = getSegmentDist(v, p1, p2, pos);
00650 if( dist < nearest)
00651 {
00652 nearest = dist;
00653 nearPos = pos;
00654 }
00655 }
00656 distance = nearest;
00657 }
00658 return false;
00659 }
00660
00661
00662 vMax = vMin = points[0];
00663 for (i = 0; i < points.size(); ++i)
00664 {
00665 vMin.x = min(vMin.x, points[i].x);
00666 vMin.y = min(vMin.y, points[i].y);
00667 vMax.x = max(vMax.x, points[i].x);
00668 vMax.y = max(vMax.y, points[i].y);
00669 }
00670
00671 if ((v.x < vMin.x) || (v.y < vMin.y) || (v.x > vMax.x) || (v.y > vMax.y))
00672 {
00673
00674 for (uint i=0; i<points.size(); ++i)
00675 {
00676 float dist = getSegmentDist(v, points[i], points[(i+1) % points.size()], pos);
00677
00678 if (dist < nearest)
00679 {
00680 nearest = dist;
00681 nearPos = pos;
00682 }
00683 }
00684 distance = nearest;
00685 return false;
00686 }
00687
00688 uint32 nNbIntersection = 0;
00689 for (i = 0; i < points.size(); ++i)
00690 {
00691 const CVector &p1 = points[i];
00692 const CVector &p2 = points[(i+1)%points.size()];
00693
00694 float dist = getSegmentDist(v, p1, p2, pos);
00695 if( dist < nearest)
00696 {
00697 nearest = dist;
00698 nearPos = pos;
00699 }
00700
00701 if (((p1.y-v.y) < 0.0)&&((p2.y-v.y) < 0.0))
00702 continue;
00703 if (((p1.y-v.y) > 0.0)&&((p2.y-v.y) > 0.0))
00704 continue;
00705 float xinter = p1.x + (p2.x-p1.x) * ((v.y-p1.y)/(p2.y-p1.y));
00706 if (xinter > v.x)
00707 ++nNbIntersection;
00708 }
00709
00710 distance = nearest;
00711 if ((nNbIntersection&1) == 1)
00712 return true;
00713 else
00714 return false;
00715 }
00716
00717
00718
00719 bool CPrimZone::contains (const NLMISC::CVector &v, const std::vector<CVector> &points, float &distance, NLMISC::CVector &nearPos, bool isPath)
00720 {
00721 uint32 i;
00722 CVector vMin, vMax;
00723 float nearest = FLT_MAX;
00724 CVector pos;
00725
00726
00727 if (points.size() < 3 || isPath)
00728 {
00729
00730 if (points.size() == 1)
00731 {
00732 distance = (points[0] - v).norm();
00733 nearPos = points[0];
00734 }
00735 else if (points.size() == 2)
00736 {
00737 distance = getSegmentDist(v, points[0], points[1], nearPos);
00738 }
00739 else
00740 {
00741
00742 for (i = 0; i < points.size()-1; ++i)
00743 {
00744 const CVector &p1 = points[i];
00745 const CVector &p2 = points[i+1];
00746
00747 float dist = getSegmentDist(v, p1, p2, pos);
00748 if( dist < nearest)
00749 {
00750 nearest = dist;
00751 nearPos = pos;
00752 }
00753 }
00754 distance = nearest;
00755 }
00756 return false;
00757 }
00758
00759
00760 vMax = vMin = points[0];
00761 for (i = 0; i < points.size(); ++i)
00762 {
00763 vMin.x = min(vMin.x, points[i].x);
00764 vMin.y = min(vMin.y, points[i].y);
00765 vMax.x = max(vMax.x, points[i].x);
00766 vMax.y = max(vMax.y, points[i].y);
00767 }
00768
00769 if ((v.x < vMin.x) || (v.y < vMin.y) || (v.x > vMax.x) || (v.y > vMax.y))
00770 {
00771
00772 for (uint i=0; i<points.size(); ++i)
00773 {
00774 float dist = getSegmentDist(v, points[i], points[(i+1) % points.size()], pos);
00775
00776 if (dist < nearest)
00777 {
00778 nearest = dist;
00779 nearPos = pos;
00780 }
00781 }
00782 distance = nearest;
00783 return false;
00784 }
00785
00786 uint32 nNbIntersection = 0;
00787 for (i = 0; i < points.size(); ++i)
00788 {
00789 const CVector &p1 = points[i];
00790 const CVector &p2 = points[(i+1)%points.size()];
00791
00792 float dist = getSegmentDist(v, p1, p2, pos);
00793 if( dist < nearest)
00794 {
00795 nearest = dist;
00796 nearPos = pos;
00797 }
00798
00799 if (((p1.y-v.y) < 0.0)&&((p2.y-v.y) < 0.0))
00800 continue;
00801 if (((p1.y-v.y) > 0.0)&&((p2.y-v.y) > 0.0))
00802 continue;
00803 float xinter = p1.x + (p2.x-p1.x) * ((v.y-p1.y)/(p2.y-p1.y));
00804 if (xinter > v.x)
00805 ++nNbIntersection;
00806 }
00807
00808 distance = nearest;
00809 if ((nNbIntersection&1) == 1)
00810 return true;
00811 else
00812 return false;
00813 }
00814
00815
00816
00817 float CPrimZone::getSegmentDist(const NLMISC::CVector v, const NLMISC::CVector &p1, const NLMISC::CVector &p2, NLMISC::CVector &nearPos)
00818 {
00819
00820 CVector V = (p2-p1).normed();
00821 float t = ((v-p1)*V)/(p2-p1).norm();
00822 float distance;
00823 if (t < 0.0f)
00824 {
00825 nearPos = p1;
00826 distance = (p1-v).norm();
00827 }
00828 else if (t > 1.0f)
00829 {
00830 nearPos = p2;
00831 distance = (p2-v).norm();
00832 }
00833 else
00834 {
00835 nearPos = p1 + t*(p2-p1);
00836 distance = (v-nearPos).norm();
00837 }
00838
00839 return distance;
00840 }
00841
00842
00843
00844
00845 void CPrimZone::serial (IStream &f)
00846 {
00847 f.xmlPushBegin ("ZONE");
00848
00849 f.xmlSetAttrib ("NAME");
00850 f.serial (Name);
00851 f.xmlSetAttrib ("LAYER");
00852 f.serial (Layer);
00853 f.xmlPushEnd ();
00854
00855 f.serialCont (VPoints);
00856
00857 f.xmlPop ();
00858 }
00859
00860
00861 void CPrimRegion::serial (IStream &f)
00862 {
00863 f.xmlPushBegin ("REGION");
00864
00865 f.xmlSetAttrib ("NAME");
00866 f.serial (Name);
00867
00868 f.xmlPushEnd();
00869
00870 sint version = 2;
00871 version = f.serialVersion (version);
00872 string check = "REGION";
00873 f.serialCheck (check);
00874
00875 f.xmlPush ("POINTS");
00876 f.serialCont (VPoints);
00877 f.xmlPop ();
00878 f.xmlPush ("PATHES");
00879 f.serialCont (VPaths);
00880 f.xmlPop ();
00881 f.xmlPush ("ZONES");
00882 f.serialCont (VZones);
00883 f.xmlPop ();
00884
00885 if (version > 1)
00886 {
00887 f.xmlPush ("HIDEPOINTS");
00888 f.serialCont (VHidePoints);
00889 f.xmlPop ();
00890 f.xmlPush ("HIDEZONES");
00891 f.serialCont (VHideZones);
00892 f.xmlPop ();
00893 f.xmlPush ("HIDEPATHS");
00894 f.serialCont (VHidePaths);
00895 f.xmlPop ();
00896 }
00897 else
00898 {
00899 VHidePoints.resize (VPoints.size(), false);
00900 VHideZones.resize (VZones.size(), false);
00901 VHidePaths.resize (VPaths.size(), false);
00902 }
00903 }
00904
00905
00906
00907
00908
00909 IPrimitive::IPrimitive (const IPrimitive &node)
00910 {
00911 _Parent = NULL;
00912 IPrimitive::operator= (node);
00913 }
00914
00915
00916
00917 IPrimitive* IPrimitive::copy () const
00918 {
00919
00920
00921
00922 IPrimitive *theCopy;
00923
00924
00925 const CPrimNode *primNode = dynamic_cast<const CPrimNode*>(this);
00926 if (primNode)
00927 {
00928 theCopy = new CPrimNode;
00929 *(CPrimNode*)theCopy = *(const CPrimNode*)this;
00930 }
00931 else
00932 {
00933
00934 const CPrimPoint *pointNode = dynamic_cast<const CPrimPoint*>(this);
00935 if (pointNode)
00936 {
00937 theCopy = new CPrimPoint;
00938 *(CPrimPoint*)theCopy = *(const CPrimPoint*)this;
00939 }
00940 else
00941 {
00942
00943 const CPrimPath *pathNode = dynamic_cast<const CPrimPath*>(this);
00944 if (pathNode)
00945 {
00946 theCopy = new CPrimPath;
00947 *(CPrimPath*)theCopy = *(const CPrimPath*)this;
00948 }
00949 else
00950 {
00951
00952 const CPrimZone *zoneNode = dynamic_cast<const CPrimZone*>(this);
00953 nlverify (zoneNode);
00954 theCopy = new CPrimZone;
00955 *(CPrimZone*)theCopy = *(const CPrimZone*)this;
00956 }
00957 }
00958 }
00959
00960
00961
00962 theCopy->_Children.resize (_Children.size ());
00963 for (uint child = 0; child < _Children.size (); child++)
00964 {
00965
00966 theCopy->_Children[child] = _Children[child]->copy ();
00967
00968
00969 theCopy->_Children[child]->_Parent = theCopy;
00970 }
00971
00972
00973 std::map<std::string, IProperty*>::const_iterator ite = _Properties.begin ();
00974 while (ite != _Properties.end ())
00975 {
00976
00977 CPropertyString *propString = dynamic_cast<CPropertyString *>(ite->second);
00978 if (propString)
00979 {
00980
00981 CPropertyString *newProp = new CPropertyString ();
00982 *newProp = *propString;
00983 theCopy->_Properties.insert (std::map<std::string, IProperty*>::value_type (ite->first, newProp));
00984 }
00985 else
00986 {
00987 CPropertyStringArray *propStringArray = dynamic_cast<CPropertyStringArray *>(ite->second);
00988 if (propStringArray)
00989 {
00990
00991 CPropertyStringArray *newProp = new CPropertyStringArray ();
00992 *newProp = *propStringArray;
00993 theCopy->_Properties.insert (std::map<std::string, IProperty*>::value_type (ite->first, newProp));
00994 }
00995 else
00996 {
00997 CPropertyColor *propColor = dynamic_cast<CPropertyColor *>(ite->second);
00998 nlverify (propColor);
00999
01000
01001 CPropertyColor *newProp = new CPropertyColor ();
01002 *newProp = *propColor;
01003 theCopy->_Properties.insert (std::map<std::string, IProperty*>::value_type (ite->first, newProp));
01004 }
01005 }
01006
01007 ite++;
01008 }
01009
01010 return theCopy;
01011 }
01012
01013
01014
01015 void IPrimitive::operator= (const IPrimitive &node)
01016 {
01017
01018 removeChildren ();
01019 removeProperties ();
01020
01021
01022 _Children.resize (node._Children.size ());
01023 for (uint child = 0; child < node._Children.size (); child++)
01024 {
01025
01026 _Children[child] = node._Children[child]->copy ();
01027
01028
01029 _Children[child]->_Parent = this;
01030 }
01031
01032
01033 std::map<std::string, IProperty*>::const_iterator ite = node._Properties.begin ();
01034 while (ite != node._Properties.end ())
01035 {
01036
01037 CPropertyString *propString = dynamic_cast<CPropertyString *>(ite->second);
01038 if (propString)
01039 {
01040
01041 CPropertyString *newProp = new CPropertyString ();
01042 *newProp = *propString;
01043 _Properties.insert (std::map<std::string, IProperty*>::value_type (ite->first, newProp));
01044 }
01045 else
01046 {
01047 CPropertyStringArray *propStringArray = dynamic_cast<CPropertyStringArray *>(ite->second);
01048 if (propStringArray)
01049 {
01050
01051 CPropertyStringArray *newProp = new CPropertyStringArray ();
01052 *newProp = *propStringArray;
01053 _Properties.insert (std::map<std::string, IProperty*>::value_type (ite->first, newProp));
01054 }
01055 else
01056 {
01057 CPropertyColor *propColor = dynamic_cast<CPropertyColor *>(ite->second);
01058 nlverify (propColor);
01059
01060
01061 CPropertyColor *newProp = new CPropertyColor ();
01062 *newProp = *propColor;
01063 _Properties.insert (std::map<std::string, IProperty*>::value_type (ite->first, newProp));
01064 }
01065 }
01066
01067 ite++;
01068 }
01069 }
01070
01071
01072
01073 bool IPrimitive::getProperty (uint index, std::string &property_name, const IProperty *&result) const
01074 {
01075
01076 std::map<std::string, IProperty*>::const_iterator ite = _Properties.begin ();
01077 while (ite != _Properties.end ())
01078 {
01079 if (index == 0)
01080 {
01081 property_name = ite->first;
01082 result = ite->second;
01083 return true;
01084 }
01085 index--;
01086 ite ++;
01087 }
01088 nlwarning ("NLLIGO::IPrimitive::getProperty : invalid index (index : %d, size : %d).", index, _Properties.size ());
01089 return false;
01090 }
01091
01092
01093
01094 bool IPrimitive::getProperty (uint index, std::string &property_name, IProperty *&result)
01095 {
01096
01097 std::map<std::string, IProperty*>::iterator ite = _Properties.begin ();
01098 while (ite != _Properties.end ())
01099 {
01100 if (index == 0)
01101 {
01102 property_name = ite->first;
01103 result = ite->second;
01104 return true;
01105 }
01106 index--;
01107 ite ++;
01108 }
01109 nlwarning ("NLLIGO::IPrimitive::getProperty : invalid index (index : %d, size : %d).", index, _Properties.size ());
01110 return false;
01111 }
01112
01113
01114
01115 bool IPrimitive::getPropertyByName (const char *property_name, const IProperty *&result) const
01116 {
01117
01118 std::map<std::string, IProperty*>::const_iterator ite = _Properties.find (property_name);
01119 if (ite != _Properties.end ())
01120 {
01121 result = ite->second;
01122 return true;
01123 }
01124 return false;
01125 }
01126
01127
01128
01129 bool IPrimitive::getPropertyByName (const char *property_name, IProperty *&result)
01130 {
01131
01132 std::map<std::string, IProperty*>::iterator ite = _Properties.find (property_name);
01133 if (ite != _Properties.end ())
01134 {
01135 result = ite->second;
01136 return true;
01137 }
01138 return false;
01139 }
01140
01141
01142
01143 bool IPrimitive::getPropertyByName (const char *property_name, std::string *&result)
01144 {
01145
01146 IProperty *prop;
01147 if (getPropertyByName (property_name, prop))
01148 {
01149 CPropertyString *strProp = dynamic_cast<CPropertyString *> (prop);
01150 if (strProp)
01151 {
01152 result = &(strProp->String);
01153 return true;
01154 }
01155 else
01156 {
01157 nlwarning ("NLLIGO::IPrimitive::getPropertyByName : property (%s) in not a string.", property_name);
01158 }
01159 }
01160 return false;
01161 }
01162
01163
01164
01165 bool IPrimitive::getPropertyByName (const char *property_name, std::string &result) const
01166 {
01167
01168 const IProperty *prop;
01169 if (getPropertyByName (property_name, prop))
01170 {
01171 const CPropertyString *strProp = dynamic_cast<const CPropertyString *> (prop);
01172 if (strProp)
01173 {
01174 result = strProp->String;
01175 return true;
01176 }
01177 else
01178 {
01179 nlwarning ("NLLIGO::IPrimitive::getPropertyByName : property (%s) in not a string.", property_name);
01180 }
01181 }
01182 return false;
01183 }
01184
01185
01186
01187 bool IPrimitive::getPropertyByName (const char *property_name, std::vector<std::string> *&result)
01188 {
01189
01190 IProperty *prop;
01191 if (getPropertyByName (property_name, prop))
01192 {
01193 CPropertyStringArray *strProp = dynamic_cast<CPropertyStringArray *> (prop);
01194 if (strProp)
01195 {
01196 result = &(strProp->StringArray);
01197 return true;
01198 }
01199 else
01200 {
01201 nlwarning ("NLLIGO::IPrimitive::getPropertyByName : property (%s) in not a string.", property_name);
01202 }
01203 }
01204 return false;
01205 }
01206
01207
01208
01209 bool IPrimitive::getPropertyByName (const char *property_name, const std::vector<std::string> *&result) const
01210 {
01211
01212 IProperty *prop;
01213 if (getPropertyByName (property_name, prop))
01214 {
01215 const CPropertyStringArray *strProp = dynamic_cast<const CPropertyStringArray *> (prop);
01216 if (strProp)
01217 {
01218 result = &(strProp->StringArray);
01219 return true;
01220 }
01221 else
01222 {
01223 nlwarning ("NLLIGO::IPrimitive::getPropertyByName : property (%s) in not a string.", property_name);
01224 }
01225 }
01226 return false;
01227 }
01228
01229
01230
01231 bool IPrimitive::getPropertyByName (const char *property_name, NLMISC::CRGBA &result) const
01232 {
01233
01234 IProperty *prop;
01235 if (getPropertyByName (property_name, prop))
01236 {
01237 const CPropertyColor *colorProp = dynamic_cast<const CPropertyColor *> (prop);
01238 if (colorProp)
01239 {
01240 result = colorProp->Color;
01241 return true;
01242 }
01243 else
01244 {
01245 nlwarning ("NLLIGO::IPrimitive::getPropertyByName : property (%s) in not a color.", property_name);
01246 }
01247 }
01248 return false;
01249 }
01250
01251
01252
01253 bool IPrimitive::removeProperty (uint index)
01254 {
01255
01256 std::map<std::string, IProperty*>::iterator ite = _Properties.begin ();
01257 while (ite != _Properties.end ())
01258 {
01259 if (index == 0)
01260 {
01261 _Properties.erase (ite);
01262 return true;
01263 }
01264 index--;
01265 ite ++;
01266 }
01267 nlwarning ("NLLIGO::IPrimitive::removeProperty : invalid index (index : %d, size : %d).", index, _Properties.size ());
01268 return false;
01269 }
01270
01271
01272
01273 bool IPrimitive::removePropertyByName (const char *property_name)
01274 {
01275
01276 std::map<std::string, IProperty*>::iterator ite = _Properties.find (property_name);
01277 if (ite != _Properties.end ())
01278 {
01279 _Properties.erase (ite);
01280 return true;
01281 }
01282 return false;
01283 }
01284
01285
01286
01287 void IPrimitive::removeProperties ()
01288 {
01289 std::map<std::string, IProperty*>::iterator ite = _Properties.begin ();
01290 while (ite != _Properties.end ())
01291 {
01292 delete ite->second;
01293 ite++;
01294 }
01295 _Properties.clear ();
01296 }
01297
01298
01299
01300 bool IPrimitive::getChild (const IPrimitive *&result, uint childId) const
01301 {
01302 if (childId < _Children.size ())
01303 {
01304 result = _Children[childId];
01305 return true;
01306 }
01307 else
01308 {
01309 nlwarning ("NLLIGO::IPrimitive::getChild : invalid index (index : %d, size %d).", childId, _Children.size ());
01310 }
01311 return false;
01312 }
01313
01314
01315
01316 bool IPrimitive::getChild (IPrimitive *&result, uint childId)
01317 {
01318 if (childId < _Children.size ())
01319 {
01320 result = _Children[childId];
01321 return true;
01322 }
01323 else
01324 {
01325 nlwarning ("NLLIGO::IPrimitive::getChild : invalid index (index : %d, size %d).", childId, _Children.size ());
01326 }
01327 return false;
01328 }
01329
01330
01331
01332 bool IPrimitive::removeChild (uint childId)
01333 {
01334 if (childId < _Children.size ())
01335 {
01336 delete _Children[childId];
01337 _Children.erase (_Children.begin()+childId);
01338 return true;
01339 }
01340 else
01341 {
01342 nlwarning ("NLLIGO::IPrimitive::removeChild : invalid index (index : %d, size %d).", childId, _Children.size ());
01343 }
01344 return false;
01345 }
01346
01347
01348
01349 void IPrimitive::removeChildren ()
01350 {
01351
01352 for (uint i=0; i<_Children.size (); i++)
01353 {
01354 delete _Children[i];
01355 }
01356 _Children.clear ();
01357 }
01358
01359
01360
01361 bool IPrimitive::insertChild (IPrimitive *primitive, uint index)
01362 {
01363
01364 if (index == AtTheEnd)
01365 index = _Children.size ();
01366
01367
01368 if (index>_Children.size ())
01369 return false;
01370
01371
01372 _Children.insert (_Children.begin () + index, primitive);
01373
01374
01375 primitive->_Parent = this;
01376
01377 return true;
01378 }
01379
01380
01381
01382 IPrimitive::~IPrimitive ()
01383 {
01384
01385 removeChildren ();
01386
01387
01388 removeProperties ();
01389 }
01390
01391
01392
01393 bool IPrimitive::addPropertyByName (const char *property_name, IProperty *result)
01394 {
01395 bool inserted = _Properties.insert (std::map<std::string, IProperty*>::value_type (property_name, result)).second;
01396 if (inserted)
01397 {
01398 return true;
01399 }
01400 return false;
01401 }
01402
01403
01404
01405 bool IPrimitive::read (xmlNodePtr xmlNode, const char *filename, uint version)
01406 {
01407
01408 _Properties.clear ();
01409
01410
01411 xmlNodePtr propNode;
01412 propNode = CIXml::getFirstChildNode (xmlNode, "PROPERTY");
01413 if (propNode)
01414 {
01415 do
01416 {
01417
01418 string name;
01419 if (GetNodeString (name, filename, propNode, "NAME"))
01420 {
01421
01422 string type;
01423 if (GetPropertyString (type, filename, propNode, "TYPE"))
01424 {
01425
01426 IProperty *property = NULL;
01427
01428
01429 if (type == "string")
01430 {
01431
01432 CPropertyString *propertyString = new CPropertyString;
01433 property = propertyString;
01434
01435
01436 if (!GetNodeString (propertyString->String, filename, propNode, "STRING"))
01437 {
01438 return false;
01439 }
01440 }
01441 else if (type == "string_array")
01442 {
01443
01444 CPropertyStringArray *propertyStringArray = new CPropertyStringArray;
01445 property = propertyStringArray;
01446
01447
01448 xmlNodePtr stringNode;
01449 propertyStringArray->StringArray.reserve (CIXml::countChildren (xmlNode, "STRING"));
01450 stringNode = CIXml::getFirstChildNode (xmlNode, "STRING");
01451 if (stringNode)
01452 {
01453 do
01454 {
01455
01456 string content;
01457 GetContentString (content, filename, stringNode);
01458 propertyStringArray->StringArray.push_back (content);
01459 }
01460 while ((stringNode = CIXml::getNextChildNode (stringNode, "STRING")));
01461 }
01462 }
01463 else if (type == "color")
01464 {
01465
01466 CPropertyColor *propertyColor= new CPropertyColor;
01467 property = propertyColor;
01468
01469
01470 xmlNodePtr colorNode;
01471 colorNode = CIXml::getFirstChildNode (xmlNode, "COLOR");
01472 string R, G, B, A;
01473 if (GetPropertyString (R, filename, colorNode, "R") &&
01474 GetPropertyString (G, filename, colorNode, "G") &&
01475 GetPropertyString (B, filename, colorNode, "B") &&
01476 GetPropertyString (A, filename, colorNode, "A"))
01477 {
01478 sint32 sR=0, sG=0, sB=0, sA=255;
01479 sR = atoi (R.c_str ());
01480 clamp (sR, 0, 255);
01481 sG = atoi (G.c_str ());
01482 clamp (sG, 0, 255);
01483 sB = atoi (B.c_str ());
01484 clamp (sB, 0, 255);
01485 sA = atoi (A.c_str ());
01486 clamp (sR, 0, 255);
01487 propertyColor->Color.R = (uint8)sR;
01488 propertyColor->Color.G = (uint8)sG;
01489 propertyColor->Color.B = (uint8)sB;
01490 propertyColor->Color.A = (uint8)sA;
01491 }
01492 else
01493 return false;
01494 }
01495
01496
01497 if (property == NULL)
01498 {
01499 XMLError (propNode, filename, "IPrimitive::read : Unknown property type (%s)", type.c_str ());
01500 return false;
01501 }
01502
01503
01504 _Properties.insert (std::map<std::string, IProperty*>::value_type (name, property));
01505 }
01506 else
01507 {
01508 return false;
01509 }
01510 }
01511 else
01512 {
01513 return false;
01514 }
01515 }
01516 while (propNode = CIXml::getNextChildNode (propNode, "PROPERTY"));
01517 }
01518
01519
01520 xmlNodePtr childNode;
01521 childNode = CIXml::getFirstChildNode (xmlNode, "CHILD");
01522 if (childNode)
01523 {
01524 do
01525 {
01526
01527 string type;
01528 if (GetPropertyString (type, filename, childNode, "TYPE"))
01529 {
01530
01531 IPrimitive *primitive = NULL;
01532
01533
01534 if (type == "node")
01535 {
01536
01537 primitive = new CPrimNode;
01538 }
01539 else if (type == "point")
01540 {
01541
01542 primitive = new CPrimPoint;
01543 }
01544 else if (type == "path")
01545 {
01546
01547 primitive = new CPrimPath;
01548 }
01549 else if (type == "zone")
01550 {
01551
01552 primitive = new CPrimZone;
01553 }
01554
01555
01556 if (primitive == NULL)
01557 {
01558 XMLError (childNode, filename, "IPrimitive::read : Unknown primitive type (%s)", type.c_str ());
01559 return false;
01560 }
01561
01562
01563 primitive->read (childNode, filename, version);
01564
01565
01566 insertChild (primitive);
01567 }
01568 else
01569 {
01570 return false;
01571 }
01572 }
01573 while (childNode = CIXml::getNextChildNode (childNode, "CHILD"));
01574 }
01575
01576
01577 return true;
01578 }
01579
01580
01581
01582 void IPrimitive::write (xmlNodePtr xmlNode, const char *filename) const
01583 {
01584
01585 std::map<std::string, IProperty*>::const_iterator ite = _Properties.begin ();
01586 while (ite != _Properties.end ())
01587 {
01588
01589 xmlNodePtr propNode = xmlNewChild ( xmlNode, NULL, (const xmlChar*)"PROPERTY", NULL);
01590 xmlNodePtr nameNode = xmlNewChild ( propNode, NULL, (const xmlChar*)"NAME", NULL);
01591 xmlNodePtr textNode = xmlNewText ((const xmlChar *)(ite->first.c_str ()));
01592 xmlAddChild (nameNode, textNode);
01593
01594
01595 const CPropertyString *str = dynamic_cast<const CPropertyString *> (ite->second);
01596 if (str)
01597 {
01598
01599 xmlSetProp (propNode, (const xmlChar*)"TYPE", (const xmlChar*)"string");
01600
01601
01602 xmlNodePtr stringNode = xmlNewChild ( propNode, NULL, (const xmlChar*)"STRING", NULL);
01603 xmlNodePtr textNode = xmlNewText ((const xmlChar *)(str->String.c_str ()));
01604 xmlAddChild (stringNode, textNode);
01605 }
01606 else
01607 {
01608
01609 const CPropertyStringArray *array = dynamic_cast<const CPropertyStringArray *> (ite->second);
01610 if (array)
01611 {
01612
01613 xmlSetProp (propNode, (const xmlChar*)"TYPE", (const xmlChar*)"string_array");
01614
01615
01616 for (uint i=0; i<array->StringArray.size (); i++)
01617 {
01618
01619 xmlNodePtr stringNode = xmlNewChild ( propNode, NULL, (const xmlChar*)"STRING", NULL);
01620 xmlNodePtr textNode = xmlNewText ((const xmlChar *)(array->StringArray[i].c_str ()));
01621 xmlAddChild (stringNode, textNode);
01622 }
01623 }
01624 else
01625 {
01626
01627 const CPropertyColor *color = safe_cast<const CPropertyColor *> (ite->second);
01628
01629
01630 xmlSetProp (propNode, (const xmlChar*)"TYPE", (const xmlChar*)"color");
01631
01632
01633 xmlNodePtr colorNode = xmlNewChild ( propNode, NULL, (const xmlChar*)"COLOR", NULL);
01634 xmlSetProp (colorNode, (const xmlChar*)"R", (const xmlChar*)toString (color->Color.R).c_str ());
01635 xmlSetProp (colorNode, (const xmlChar*)"G", (const xmlChar*)toString (color->Color.G).c_str ());
01636 xmlSetProp (colorNode, (const xmlChar*)"B", (const xmlChar*)toString (color->Color.B).c_str ());
01637 xmlSetProp (colorNode, (const xmlChar*)"A", (const xmlChar*)toString (color->Color.A).c_str ());
01638 }
01639 }
01640
01641 ite++;
01642 }
01643
01644
01645 for (uint i=0; i<_Children.size (); i++)
01646 {
01647
01648 xmlNodePtr childNode = xmlNewChild ( xmlNode, NULL, (const xmlChar*)"CHILD", NULL);
01649
01650
01651 _Children[i]->write (childNode, filename);
01652 }
01653 }
01654
01655
01656
01657 bool IPrimitive::getChildId (uint &childId, const IPrimitive *child) const
01658 {
01659 const uint childrenSize = _Children.size ();
01660 for (uint i=0; i<childrenSize; i++)
01661 {
01662 if (_Children[i] == child)
01663 {
01664 childId = i;
01665 return true;
01666 }
01667 }
01668 childId = 0xffffffff;
01669 return false;
01670 }
01671
01672
01673
01674 uint IPrimitive::getNumProperty () const
01675 {
01676 return _Properties.size ();
01677 }
01678
01679
01680
01681
01682
01683 bool CPrimitives::read (xmlNodePtr xmlNode, const char *filename)
01684 {
01685 nlassert (xmlNode);
01686
01687
01688 if (strcmp ((const char*)xmlNode->name, "PRIMITIVES") == 0)
01689 {
01690
01691 string versionName = "0";
01692 if (GetPropertyString (versionName, filename, xmlNode, "VERSION"))
01693 {
01694
01695 uint version = atoi (versionName.c_str ());
01696
01697
01698 if (version <= NLLIGO_PRIMITVE_VERSION)
01699 {
01700
01701 xmlNode = GetFirstChildNode (xmlNode, filename, "ROOT_PRIMITIVE");
01702 if (xmlNode)
01703 {
01704
01705 ((IPrimitive*)&RootNode)->read (xmlNode, filename, version);
01706 }
01707 }
01708 else
01709 {
01710 Error (filename, "CPrimitives::read : Unknown file version (%d)", version);
01711 return false;
01712 }
01713 }
01714 else
01715 {
01716 return false;
01717 }
01718 }
01719 else
01720 {
01721 XMLError (xmlNode, filename, "This XML document is not a NeL primitive file");
01722 return false;
01723 }
01724
01725 return true;
01726 }
01727
01728
01729
01730 void CPrimitives::write (xmlDocPtr doc, const char *filename) const
01731 {
01732 nlassert (doc);
01733
01734
01735 xmlNodePtr primNode = xmlNewDocNode (doc, NULL, (const xmlChar*)"PRIMITIVES", NULL);
01736 xmlDocSetRootElement (doc, primNode);
01737
01738
01739 xmlSetProp (primNode, (const xmlChar*)"VERSION", (const xmlChar*)toString (NLLIGO_PRIMITVE_VERSION).c_str ());
01740
01741
01742 xmlNodePtr nameNode = xmlNewChild ( primNode, NULL, (const xmlChar*)"ROOT_PRIMITIVE", NULL);
01743
01744
01745 ((IPrimitive*)&RootNode)->write (nameNode, filename);
01746 }
01747
01748
01749
01750 void CPrimitives::convertAddPrimitive (IPrimitive *child, const IPrimitive *prim, bool hidden)
01751 {
01752
01753 IPrimitive *primitive = NULL;
01754
01755
01756 const CPrimPoint *oldPoint = dynamic_cast<const CPrimPoint *>(prim);
01757 if (oldPoint)
01758 {
01759
01760 CPrimPoint *point = new CPrimPoint ();
01761 primitive = point;
01762
01763
01764 *point = *oldPoint;
01765 }
01766 else
01767 {
01768
01769 const CPrimPath *oldPath = dynamic_cast<const CPrimPath *>(prim);
01770 if (oldPath)
01771 {
01772
01773 CPrimPath *path = new CPrimPath ();
01774 primitive = path;
01775
01776
01777 *path = *oldPath;
01778 }
01779 else
01780 {
01781 const CPrimZone *oldZone = safe_cast<const CPrimZone *>(prim);
01782 if (oldZone)
01783 {
01784
01785 CPrimZone *zone = new CPrimZone ();
01786 primitive = zone;
01787
01788
01789 *zone = *oldZone;
01790 }
01791 }
01792 }
01793
01794
01795 if (primitive)
01796 {
01797
01798 CPropertyString *nameProp = new CPropertyString;
01799 nameProp->String = prim->Name;
01800
01801
01802 primitive->addPropertyByName ("Name", nameProp);
01803
01804
01805 if (hidden)
01806 {
01807
01808 nameProp = new CPropertyString;
01809
01810
01811 primitive->addPropertyByName ("Hidden", nameProp);
01812 }
01813
01814
01815 child->insertChild (primitive);
01816 }
01817 }
01818
01819
01820
01821 void CPrimitives::convertPrimitive (const IPrimitive *prim, bool hidden)
01822 {
01823
01824 uint numChildren = RootNode.getNumChildren ();
01825 uint j;
01826 for (j=0; j<numChildren; j++)
01827 {
01828 IPrimitive *child;
01829 nlverify (RootNode.getChild (child, j));
01830 const IProperty *prop;
01831 if (child->getPropertyByName ("Name", prop))
01832 {
01833
01834 const CPropertyString *name = dynamic_cast<const CPropertyString *>(prop);
01835 if (name)
01836 {
01837
01838 if (name->String == prim->Layer)
01839 {
01840 convertAddPrimitive (child, prim, hidden);
01841 break;
01842 }
01843 }
01844 }
01845 }
01846
01847
01848 if (j==numChildren)
01849 {
01850
01851 CPrimNode *primNode = new CPrimNode;
01852
01853
01854 CPropertyString *nameProp = new CPropertyString;
01855 nameProp->String = prim->Layer;
01856
01857
01858 primNode->addPropertyByName ("Name", nameProp);
01859
01860
01861 RootNode.insertChild (primNode);
01862
01863
01864 convertAddPrimitive (primNode, prim, hidden);
01865 }
01866 }
01867
01868
01869
01870 void CPrimitives::convert (const CPrimRegion ®ion)
01871 {
01872
01873 RootNode.removeChildren ();
01874 RootNode.removeProperties ();
01875
01876
01877 uint i;
01878 for (i=0; i<region.VPoints.size (); i++)
01879 {
01880 convertPrimitive (&(region.VPoints[i]), region.VHidePoints[i]);
01881 }
01882 for (i=0; i<region.VPaths.size (); i++)
01883 {
01884 convertPrimitive (&(region.VPaths[i]), region.VHidePaths[i]);
01885 }
01886 for (i=0; i<region.VZones.size (); i++)
01887 {
01888 convertPrimitive (&(region.VZones[i]), region.VHideZones[i]);
01889 }
01890 }
01891
01892
01893
01894
01895 }
01896