Changeset be2997 for molecuilder/src/tesselationhelpers.cpp
- Timestamp:
- Nov 25, 2009, 3:29:18 PM (16 years ago)
- Children:
- 3aa635
- Parents:
- edf611
- File:
-
- 1 edited
-
molecuilder/src/tesselationhelpers.cpp (modified) (41 diffs)
Legend:
- Unmodified
- Added
- Removed
-
molecuilder/src/tesselationhelpers.cpp
redf611 rbe2997 8 8 #include <fstream> 9 9 10 #include "info.hpp" 10 11 #include "linkedcell.hpp" 11 12 #include "log.hpp" … … 15 16 #include "verbose.hpp" 16 17 17 double DetGet(gsl_matrix * const A, const int inPlace) { 18 double DetGet(gsl_matrix * const A, const int inPlace) 19 { 20 Info FunctionInfo(__func__); 18 21 /* 19 22 inPlace = 1 => A is replaced with the LU decomposed copy. … … 45 48 void GetSphere(Vector * const center, const Vector &a, const Vector &b, const Vector &c, const double RADIUS) 46 49 { 50 Info FunctionInfo(__func__); 47 51 gsl_matrix *A = gsl_matrix_calloc(3,3); 48 52 double m11, m12, m13, m14; … … 111 115 const double HalfplaneIndicator, const double AlternativeIndicator, const double alpha, const double beta, const double gamma, const double RADIUS, const double Umkreisradius) 112 116 { 117 Info FunctionInfo(__func__); 113 118 Vector TempNormal, helper; 114 119 double Restradius; 115 120 Vector OtherCenter; 116 Log() << Verbose(3) << "Begin of GetCenterOfSphere.\n";117 121 Center->Zero(); 118 122 helper.CopyVector(&a); … … 128 132 Center->Scale(1./(sin(2.*alpha) + sin(2.*beta) + sin(2.*gamma))); 129 133 NewUmkreismittelpunkt->CopyVector(Center); 130 Log() << Verbose( 4) << "Center of new circumference is " << *NewUmkreismittelpunkt << ".\n";134 Log() << Verbose(1) << "Center of new circumference is " << *NewUmkreismittelpunkt << ".\n"; 131 135 // Here we calculated center of circumscribing circle, using barycentric coordinates 132 Log() << Verbose( 4) << "Center of circumference is " << *Center << " in direction " << *Direction << ".\n";136 Log() << Verbose(1) << "Center of circumference is " << *Center << " in direction " << *Direction << ".\n"; 133 137 134 138 TempNormal.CopyVector(&a); … … 154 158 TempNormal.Normalize(); 155 159 Restradius = sqrt(RADIUS*RADIUS - Umkreisradius*Umkreisradius); 156 Log() << Verbose( 4) << "Height of center of circumference to center of sphere is " << Restradius << ".\n";160 Log() << Verbose(1) << "Height of center of circumference to center of sphere is " << Restradius << ".\n"; 157 161 TempNormal.Scale(Restradius); 158 Log() << Verbose( 4) << "Shift vector to sphere of circumference is " << TempNormal << ".\n";162 Log() << Verbose(1) << "Shift vector to sphere of circumference is " << TempNormal << ".\n"; 159 163 160 164 Center->AddVector(&TempNormal); 161 Log() << Verbose( 0) << "Center of sphere of circumference is " << *Center << ".\n";165 Log() << Verbose(1) << "Center of sphere of circumference is " << *Center << ".\n"; 162 166 GetSphere(&OtherCenter, a, b, c, RADIUS); 163 Log() << Verbose(0) << "OtherCenter of sphere of circumference is " << OtherCenter << ".\n"; 164 Log() << Verbose(3) << "End of GetCenterOfSphere.\n"; 167 Log() << Verbose(1) << "OtherCenter of sphere of circumference is " << OtherCenter << ".\n"; 165 168 }; 166 169 … … 174 177 void GetCenterofCircumcircle(Vector * const Center, const Vector &a, const Vector &b, const Vector &c) 175 178 { 179 Info FunctionInfo(__func__); 176 180 Vector helper; 177 181 double alpha, beta, gamma; … … 186 190 beta = M_PI - SideC.Angle(&SideA); 187 191 gamma = M_PI - SideA.Angle(&SideB); 188 //Log() << Verbose( 3) << "INFO: alpha = " << alpha/M_PI*180. << ", beta = " << beta/M_PI*180. << ", gamma = " << gamma/M_PI*180. << "." << endl;192 //Log() << Verbose(1) << "INFO: alpha = " << alpha/M_PI*180. << ", beta = " << beta/M_PI*180. << ", gamma = " << gamma/M_PI*180. << "." << endl; 189 193 if (fabs(M_PI - alpha - beta - gamma) > HULLEPSILON) { 190 194 eLog() << Verbose(1) << "GetCenterofCircumcircle: Sum of angles " << (alpha+beta+gamma)/M_PI*180. << " > 180 degrees by " << fabs(M_PI - alpha - beta - gamma)/M_PI*180. << "!" << endl; … … 219 223 double GetPathLengthonCircumCircle(const Vector &CircleCenter, const Vector &CirclePlaneNormal, const double CircleRadius, const Vector &NewSphereCenter, const Vector &OldSphereCenter, const Vector &NormalVector, const Vector &SearchDirection) 220 224 { 225 Info FunctionInfo(__func__); 221 226 Vector helper; 222 227 double radius, alpha; … … 236 241 if (helper.ScalarProduct(&SearchDirection) < -HULLEPSILON) // acos is not unique on [0, 2.*M_PI), hence extra check to decide between two half intervals 237 242 alpha = 2.*M_PI - alpha; 238 //Log() << Verbose( 2) << "INFO: RelativeNewSphereCenter is " << helper << ", RelativeOldSphereCenter is " << OldSphereCenter << " and resulting angle is " << alpha << "." << endl;243 //Log() << Verbose(1) << "INFO: RelativeNewSphereCenter is " << helper << ", RelativeOldSphereCenter is " << OldSphereCenter << " and resulting angle is " << alpha << "." << endl; 239 244 radius = helper.Distance(&OldSphereCenter); 240 245 helper.ProjectOntoPlane(&NormalVector); 241 246 // check whether new center is somewhat away or at least right over the current baseline to prevent intersecting triangles 242 247 if ((radius > HULLEPSILON) || (helper.Norm() < HULLEPSILON)) { 243 //Log() << Verbose( 2) << "INFO: Distance between old and new center is " << radius << " and between new center and baseline center is " << helper.Norm() << "." << endl;248 //Log() << Verbose(1) << "INFO: Distance between old and new center is " << radius << " and between new center and baseline center is " << helper.Norm() << "." << endl; 244 249 return alpha; 245 250 } else { … … 264 269 double MinIntersectDistance(const gsl_vector * x, void *params) 265 270 { 271 Info FunctionInfo(__func__); 266 272 double retval = 0; 267 273 struct Intersection *I = (struct Intersection *)params; … … 284 290 285 291 retval = HeightA.ScalarProduct(&HeightA) + HeightB.ScalarProduct(&HeightB); 286 //Log() << Verbose( 2) << "MinIntersectDistance called, result: " << retval << endl;292 //Log() << Verbose(1) << "MinIntersectDistance called, result: " << retval << endl; 287 293 288 294 return retval; … … 304 310 bool existsIntersection(const Vector &point1, const Vector &point2, const Vector &point3, const Vector &point4) 305 311 { 312 Info FunctionInfo(__func__); 306 313 bool result; 307 314 … … 351 358 352 359 if (status == GSL_SUCCESS) { 353 Log() << Verbose( 2) << "converged to minimum" << endl;360 Log() << Verbose(1) << "converged to minimum" << endl; 354 361 } 355 362 } while (status == GSL_CONTINUE && iter < 100); … … 376 383 t2 = HeightB.ScalarProduct(&SideB)/SideB.ScalarProduct(&SideB); 377 384 378 Log() << Verbose( 2) << "Intersection " << intersection << " is at "385 Log() << Verbose(1) << "Intersection " << intersection << " is at " 379 386 << t1 << " for (" << point1 << "," << point2 << ") and at " 380 387 << t2 << " for (" << point3 << "," << point4 << "): "; 381 388 382 389 if (((t1 >= 0) && (t1 <= 1)) && ((t2 >= 0) && (t2 <= 1))) { 383 Log() << Verbose( 0) << "true intersection." << endl;390 Log() << Verbose(1) << "true intersection." << endl; 384 391 result = true; 385 392 } else { 386 Log() << Verbose( 0) << "intersection out of region of interest." << endl;393 Log() << Verbose(1) << "intersection out of region of interest." << endl; 387 394 result = false; 388 395 } … … 407 414 double GetAngle(const Vector &point, const Vector &reference, const Vector &OrthogonalVector) 408 415 { 416 Info FunctionInfo(__func__); 409 417 if (reference.IsZero()) 410 418 return M_PI; … … 418 426 } 419 427 420 Log() << Verbose( 4) << "INFO: " << point << " has angle " << phi << " with respect to reference " << reference << "." << endl;428 Log() << Verbose(1) << "INFO: " << point << " has angle " << phi << " with respect to reference " << reference << "." << endl; 421 429 422 430 return phi; … … 433 441 double CalculateVolumeofGeneralTetraeder(const Vector &a, const Vector &b, const Vector &c, const Vector &d) 434 442 { 443 Info FunctionInfo(__func__); 435 444 Vector Point, TetraederVector[3]; 436 445 double volume; … … 456 465 bool CheckLineCriteriaForDegeneratedTriangle(const BoundaryPointSet * const nodes[3]) 457 466 { 467 Info FunctionInfo(__func__); 458 468 bool result = false; 459 469 int counter = 0; … … 482 492 } 483 493 if ((!result) && (counter > 1)) { 484 Log() << Verbose( 2) << "INFO: Degenerate triangle is ok, at least two, here " << counter << ", existing lines are used." << endl;494 Log() << Verbose(1) << "INFO: Degenerate triangle is ok, at least two, here " << counter << ", existing lines are used." << endl; 485 495 result = true; 486 496 } … … 489 499 490 500 491 /** Sort function for the candidate list. 492 */ 493 bool SortCandidates(const CandidateForTesselation* candidate1, const CandidateForTesselation* candidate2) 494 { 495 Vector BaseLineVector, OrthogonalVector, helper; 496 if (candidate1->BaseLine != candidate2->BaseLine) { // sanity check 497 eLog() << Verbose(1) << "sortCandidates was called for two different baselines: " << candidate1->BaseLine << " and " << candidate2->BaseLine << "." << endl; 498 //return false; 499 exit(1); 500 } 501 // create baseline vector 502 BaseLineVector.CopyVector(candidate1->BaseLine->endpoints[1]->node->node); 503 BaseLineVector.SubtractVector(candidate1->BaseLine->endpoints[0]->node->node); 504 BaseLineVector.Normalize(); 505 506 // create normal in-plane vector to cope with acos() non-uniqueness on [0,2pi] (note that is pointing in the "right" direction already, hence ">0" test!) 507 helper.CopyVector(candidate1->BaseLine->endpoints[0]->node->node); 508 helper.SubtractVector(candidate1->point->node); 509 OrthogonalVector.CopyVector(&helper); 510 helper.VectorProduct(&BaseLineVector); 511 OrthogonalVector.SubtractVector(&helper); 512 OrthogonalVector.Normalize(); 513 514 // calculate both angles and correct with in-plane vector 515 helper.CopyVector(candidate1->point->node); 516 helper.SubtractVector(candidate1->BaseLine->endpoints[0]->node->node); 517 double phi = BaseLineVector.Angle(&helper); 518 if (OrthogonalVector.ScalarProduct(&helper) > 0) { 519 phi = 2.*M_PI - phi; 520 } 521 helper.CopyVector(candidate2->point->node); 522 helper.SubtractVector(candidate1->BaseLine->endpoints[0]->node->node); 523 double psi = BaseLineVector.Angle(&helper); 524 if (OrthogonalVector.ScalarProduct(&helper) > 0) { 525 psi = 2.*M_PI - psi; 526 } 527 528 Log() << Verbose(2) << *candidate1->point << " has angle " << phi << endl; 529 Log() << Verbose(2) << *candidate2->point << " has angle " << psi << endl; 530 531 // return comparison 532 return phi < psi; 533 }; 501 ///** Sort function for the candidate list. 502 // */ 503 //bool SortCandidates(const CandidateForTesselation* candidate1, const CandidateForTesselation* candidate2) 504 //{ 505 // Info FunctionInfo(__func__); 506 // Vector BaseLineVector, OrthogonalVector, helper; 507 // if (candidate1->BaseLine != candidate2->BaseLine) { // sanity check 508 // eLog() << Verbose(1) << "sortCandidates was called for two different baselines: " << candidate1->BaseLine << " and " << candidate2->BaseLine << "." << endl; 509 // //return false; 510 // exit(1); 511 // } 512 // // create baseline vector 513 // BaseLineVector.CopyVector(candidate1->BaseLine->endpoints[1]->node->node); 514 // BaseLineVector.SubtractVector(candidate1->BaseLine->endpoints[0]->node->node); 515 // BaseLineVector.Normalize(); 516 // 517 // // create normal in-plane vector to cope with acos() non-uniqueness on [0,2pi] (note that is pointing in the "right" direction already, hence ">0" test!) 518 // helper.CopyVector(candidate1->BaseLine->endpoints[0]->node->node); 519 // helper.SubtractVector(candidate1->point->node); 520 // OrthogonalVector.CopyVector(&helper); 521 // helper.VectorProduct(&BaseLineVector); 522 // OrthogonalVector.SubtractVector(&helper); 523 // OrthogonalVector.Normalize(); 524 // 525 // // calculate both angles and correct with in-plane vector 526 // helper.CopyVector(candidate1->point->node); 527 // helper.SubtractVector(candidate1->BaseLine->endpoints[0]->node->node); 528 // double phi = BaseLineVector.Angle(&helper); 529 // if (OrthogonalVector.ScalarProduct(&helper) > 0) { 530 // phi = 2.*M_PI - phi; 531 // } 532 // helper.CopyVector(candidate2->point->node); 533 // helper.SubtractVector(candidate1->BaseLine->endpoints[0]->node->node); 534 // double psi = BaseLineVector.Angle(&helper); 535 // if (OrthogonalVector.ScalarProduct(&helper) > 0) { 536 // psi = 2.*M_PI - psi; 537 // } 538 // 539 // Log() << Verbose(1) << *candidate1->point << " has angle " << phi << endl; 540 // Log() << Verbose(1) << *candidate2->point << " has angle " << psi << endl; 541 // 542 // // return comparison 543 // return phi < psi; 544 //}; 534 545 535 546 /** … … 543 554 TesselPoint* FindSecondClosestPoint(const Vector* Point, const LinkedCell* const LC) 544 555 { 556 Info FunctionInfo(__func__); 545 557 TesselPoint* closestPoint = NULL; 546 558 TesselPoint* secondClosestPoint = NULL; … … 553 565 for(int i=0;i<NDIM;i++) // store indices of this cell 554 566 N[i] = LC->n[i]; 555 Log() << Verbose( 2) << "INFO: Center cell is " << N[0] << ", " << N[1] << ", " << N[2] << " with No. " << LC->index << "." << endl;567 Log() << Verbose(1) << "INFO: Center cell is " << N[0] << ", " << N[1] << ", " << N[2] << " with No. " << LC->index << "." << endl; 556 568 557 569 LC->GetNeighbourBounds(Nlower, Nupper); 558 //Log() << Verbose( 0) << endl;570 //Log() << Verbose(1) << endl; 559 571 for (LC->n[0] = Nlower[0]; LC->n[0] <= Nupper[0]; LC->n[0]++) 560 572 for (LC->n[1] = Nlower[1]; LC->n[1] <= Nupper[1]; LC->n[1]++) 561 573 for (LC->n[2] = Nlower[2]; LC->n[2] <= Nupper[2]; LC->n[2]++) { 562 574 const LinkedNodes *List = LC->GetCurrentCell(); 563 //Log() << Verbose( 3) << "The current cell " << LC->n[0] << "," << LC->n[1] << "," << LC->n[2] << endl;575 //Log() << Verbose(1) << "The current cell " << LC->n[0] << "," << LC->n[1] << "," << LC->n[2] << endl; 564 576 if (List != NULL) { 565 577 for (LinkedNodes::const_iterator Runner = List->begin(); Runner != List->end(); Runner++) { … … 597 609 TesselPoint* FindClosestPoint(const Vector* Point, TesselPoint *&SecondPoint, const LinkedCell* const LC) 598 610 { 611 Info FunctionInfo(__func__); 599 612 TesselPoint* closestPoint = NULL; 600 613 SecondPoint = NULL; … … 607 620 for(int i=0;i<NDIM;i++) // store indices of this cell 608 621 N[i] = LC->n[i]; 609 Log() << Verbose( 3) << "INFO: Center cell is " << N[0] << ", " << N[1] << ", " << N[2] << " with No. " << LC->index << "." << endl;622 Log() << Verbose(1) << "INFO: Center cell is " << N[0] << ", " << N[1] << ", " << N[2] << " with No. " << LC->index << "." << endl; 610 623 611 624 LC->GetNeighbourBounds(Nlower, Nupper); 612 //Log() << Verbose( 0) << endl;625 //Log() << Verbose(1) << endl; 613 626 for (LC->n[0] = Nlower[0]; LC->n[0] <= Nupper[0]; LC->n[0]++) 614 627 for (LC->n[1] = Nlower[1]; LC->n[1] <= Nupper[1]; LC->n[1]++) 615 628 for (LC->n[2] = Nlower[2]; LC->n[2] <= Nupper[2]; LC->n[2]++) { 616 629 const LinkedNodes *List = LC->GetCurrentCell(); 617 //Log() << Verbose( 3) << "The current cell " << LC->n[0] << "," << LC->n[1] << "," << LC->n[2] << endl;630 //Log() << Verbose(1) << "The current cell " << LC->n[0] << "," << LC->n[1] << "," << LC->n[2] << endl; 618 631 if (List != NULL) { 619 632 for (LinkedNodes::const_iterator Runner = List->begin(); Runner != List->end(); Runner++) { … … 626 639 distance = currentNorm; 627 640 closestPoint = (*Runner); 628 //Log() << Verbose( 2) << "INFO: New Nearest Neighbour is " << *closestPoint << "." << endl;641 //Log() << Verbose(1) << "INFO: New Nearest Neighbour is " << *closestPoint << "." << endl; 629 642 } else if (currentNorm < secondDistance) { 630 643 secondDistance = currentNorm; 631 644 SecondPoint = (*Runner); 632 //Log() << Verbose( 2) << "INFO: New Second Nearest Neighbour is " << *SecondPoint << "." << endl;645 //Log() << Verbose(1) << "INFO: New Second Nearest Neighbour is " << *SecondPoint << "." << endl; 633 646 } 634 647 } … … 640 653 // output 641 654 if (closestPoint != NULL) { 642 Log() << Verbose( 2) << "Closest point is " << *closestPoint;655 Log() << Verbose(1) << "Closest point is " << *closestPoint; 643 656 if (SecondPoint != NULL) 644 657 Log() << Verbose(0) << " and second closest is " << *SecondPoint; … … 656 669 Vector * GetClosestPointBetweenLine(const BoundaryLineSet * const Base, const BoundaryLineSet * const OtherBase) 657 670 { 671 Info FunctionInfo(__func__); 658 672 // construct the plane of the two baselines (i.e. take both their directional vectors) 659 673 Vector Normal; … … 666 680 Normal.VectorProduct(&OtherBaseline); 667 681 Normal.Normalize(); 668 Log() << Verbose( 4) << "First direction is " << Baseline << ", second direction is " << OtherBaseline << ", normal of intersection plane is " << Normal << "." << endl;682 Log() << Verbose(1) << "First direction is " << Baseline << ", second direction is " << OtherBaseline << ", normal of intersection plane is " << Normal << "." << endl; 669 683 670 684 // project one offset point of OtherBase onto this plane (and add plane offset vector) … … 683 697 Normal.CopyVector(Intersection); 684 698 Normal.SubtractVector(Base->endpoints[0]->node->node); 685 Log() << Verbose( 3) << "Found closest point on " << *Base << " at " << *Intersection << ", factor in line is " << fabs(Normal.ScalarProduct(&Baseline)/Baseline.NormSquared()) << "." << endl;699 Log() << Verbose(1) << "Found closest point on " << *Base << " at " << *Intersection << ", factor in line is " << fabs(Normal.ScalarProduct(&Baseline)/Baseline.NormSquared()) << "." << endl; 686 700 687 701 return Intersection; … … 696 710 double DistanceToTrianglePlane(const Vector *x, const BoundaryTriangleSet * const triangle) 697 711 { 712 Info FunctionInfo(__func__); 698 713 double distance = 0.; 699 714 if (x == NULL) { … … 712 727 void WriteVrmlFile(ofstream * const vrmlfile, const Tesselation * const Tess, const PointCloud * const cloud) 713 728 { 729 Info FunctionInfo(__func__); 714 730 TesselPoint *Walker = NULL; 715 731 int i; … … 755 771 void IncludeSphereinRaster3D(ofstream * const rasterfile, const Tesselation * const Tess, const PointCloud * const cloud) 756 772 { 773 Info FunctionInfo(__func__); 757 774 Vector helper; 758 775 … … 783 800 void WriteRaster3dFile(ofstream * const rasterfile, const Tesselation * const Tess, const PointCloud * const cloud) 784 801 { 802 Info FunctionInfo(__func__); 785 803 TesselPoint *Walker = NULL; 786 804 int i; … … 828 846 void WriteTecplotFile(ofstream * const tecplot, const Tesselation * const TesselStruct, const PointCloud * const cloud, const int N) 829 847 { 848 Info FunctionInfo(__func__); 830 849 if ((tecplot != NULL) && (TesselStruct != NULL)) { 831 850 // write header … … 848 867 849 868 // print atom coordinates 850 Log() << Verbose(2) << "The following triangles were created:";851 869 int Counter = 1; 852 870 TesselPoint *Walker = NULL; … … 858 876 *tecplot << endl; 859 877 // print connectivity 878 Log() << Verbose(1) << "The following triangles were created:" << endl; 860 879 for (TriangleMap::const_iterator runner = TesselStruct->TrianglesOnBoundary.begin(); runner != TesselStruct->TrianglesOnBoundary.end(); runner++) { 861 Log() << Verbose( 0) << " " << runner->second->endpoints[0]->node->Name << "<->" << runner->second->endpoints[1]->node->Name << "<->" << runner->second->endpoints[2]->node->Name;880 Log() << Verbose(1) << " " << runner->second->endpoints[0]->node->Name << "<->" << runner->second->endpoints[1]->node->Name << "<->" << runner->second->endpoints[2]->node->Name << endl; 862 881 *tecplot << LookupList[runner->second->endpoints[0]->node->nr] << " " << LookupList[runner->second->endpoints[1]->node->nr] << " " << LookupList[runner->second->endpoints[2]->node->nr] << endl; 863 882 } 864 883 delete[] (LookupList); 865 Log() << Verbose(0) << endl;866 884 } 867 885 }; … … 874 892 void CalculateConcavityPerBoundaryPoint(const Tesselation * const TesselStruct) 875 893 { 894 Info FunctionInfo(__func__); 876 895 class BoundaryPointSet *point = NULL; 877 896 class BoundaryLineSet *line = NULL; 878 897 879 //Log() << Verbose(2) << "Begin of CalculateConcavityPerBoundaryPoint" << endl;880 898 // calculate remaining concavity 881 899 for (PointMap::const_iterator PointRunner = TesselStruct->PointsOnBoundary.begin(); PointRunner != TesselStruct->PointsOnBoundary.end(); PointRunner++) { … … 885 903 for (LineMap::iterator LineRunner = point->lines.begin(); LineRunner != point->lines.end(); LineRunner++) { 886 904 line = LineRunner->second; 887 //Log() << Verbose( 2) << "INFO: Current line of point " << *point << " is " << *line << "." << endl;905 //Log() << Verbose(1) << "INFO: Current line of point " << *point << " is " << *line << "." << endl; 888 906 if (!line->CheckConvexityCriterion()) 889 907 point->value += 1; 890 908 } 891 909 } 892 //Log() << Verbose(2) << "End of CalculateConcavityPerBoundaryPoint" << endl;893 910 }; 894 911 … … 901 918 bool CheckListOfBaselines(const Tesselation * const TesselStruct) 902 919 { 920 Info FunctionInfo(__func__); 903 921 LineMap::const_iterator testline; 904 922 bool result = false; … … 908 926 for (testline = TesselStruct->LinesOnBoundary.begin(); testline != TesselStruct->LinesOnBoundary.end(); testline++) { 909 927 if (testline->second->triangles.size() != 2) { 910 Log() << Verbose( 1) << *testline->second << "\t" << testline->second->triangles.size() << endl;928 Log() << Verbose(2) << *testline->second << "\t" << testline->second->triangles.size() << endl; 911 929 counter++; 912 930 }
Note:
See TracChangeset
for help on using the changeset viewer.
