int main() { CDT cdt; cdt.insert_constraint(Point(2, 5), Point(8, 5)); cdt.insert(Point(5, 6)); cdt.insert(Point(5, 4)); std::pair<Vertex_handle,Vertex_handle> p; for(CDT::Subconstraint_iterator sit = cdt.subconstraints_begin(); sit != cdt.subconstraints_end(); ++sit){ p = (*sit).first; Vertex_handle vh1 = p.first; Vertex_handle vh2 = p.second; std::cerr << "subconstraint: " << vh1->point() << " -- " << vh2->point() << std::endl; } std::cerr << "\nMake Gabriel" << std::endl; CGAL::make_conforming_Gabriel_2(cdt); int counter = 0; for(CDT::Subconstraint_iterator sit = cdt.subconstraints_begin(); sit != cdt.subconstraints_end(); ++sit){ ++counter; p = (*sit).first; Vertex_handle vh1 = p.first; Vertex_handle vh2 = p.second; std::cerr << "subconstraint: " << vh1->point() << " -- " << vh2->point() << std::endl; } assert(counter>1); return 0; }
int main( ) { CDT cdt; std::cout << "Inserting a grid of 5x5 constraints " << std::endl; for (int i = 1; i < 6; ++i) cdt.insert_constraint( Point(0,i), Point(6,i)); for (int j = 1; j < 6; ++j) cdt.insert_constraint( Point(j,0), Point(j,6)); assert(cdt.is_valid()); int count = 0; for (CDT::Finite_edges_iterator eit = cdt.finite_edges_begin(); eit != cdt.finite_edges_end(); ++eit) if (cdt.is_constrained(*eit)) ++count; std::cout << "The number of resulting constrained edges is "; std::cout << count << std::endl; return 0; }
std::list< CgalTrian> erGeometryExtractTrianglesWithMesh( InputSegmentIterator debut, InputSegmentIterator fin,double mesh_angle=0.125,double mesh_size=4.) { CgalDT cgadt ; for( InputSegmentIterator icg=debut;icg!=fin;icg++) { cgadt.insert_constraint(icg->source(),icg->target()); }; CGAL::refine_Delaunay_mesh_2(cgadt, Criteria(mesh_angle,mesh_size)); CgalDT::Finite_edges_iterator bed,nif; // std::cout << "Nbre de noeuds:" << cgadt.number_of_vertices() << std::endl; // int i; // std::cin >> i; bed=cgadt.finite_edges_begin(); nif=cgadt.finite_edges_end(); CDT cdt; for(;bed!=nif;bed++) { CDT::Vertex_handle va = cdt.insert(bed->first->vertex(cgadt.cw(bed->second))->point()); CDT::Vertex_handle vb = cdt.insert(bed->first->vertex(cgadt.ccw(bed->second))->point()); if(cgadt.is_constrained(*bed)) { cdt.insert_constraint(va,vb); } } initializeID(cdt); discoverComponents(cdt); std::list<CgalTrian> triangs; CDT::All_faces_iterator deb=cdt.all_faces_begin(); for(;deb!=cdt.all_faces_end();deb++) { if(deb->is_in_domain()) { CgalTrian tri=cdt.triangle(deb); triangs.push_back(tri); } }; return triangs; };
// // String // static void FmtString(StringBuffer & oBuffer, const CDT & oCurrentArgument, const UINT_32 iFmtFlags, const INT_32 iWidth, const INT_32 iMaxChars, CHAR_8 chPadSymbol) { const STLW::string sTMP = oCurrentArgument.GetString(); INT_32 iFormatSize = sTMP.size(); if (iFormatSize > iMaxChars && iMaxChars > 0) { iFormatSize = iMaxChars; } if (iFmtFlags & F_LEFT_ALIGN) { oBuffer.Append(sTMP.data(), iFormatSize); if (iWidth > iFormatSize) { oBuffer.Append(iWidth - iFormatSize, chPadSymbol); } } else { if (iWidth > iFormatSize) { oBuffer.Append(iWidth - iFormatSize, chPadSymbol); } oBuffer.Append(sTMP.data(), iFormatSize); } }
int test_T2(const FT eps) { std::cout << "test_T2 (tolerance: " << eps << ")" << std::endl; std::vector<Point_2> points; Polygon_2 polygon1; polygon1.push_back(Point_2(0,0)); polygon1.push_back(Point_2(2,0)); polygon1.push_back(Point_2(2,2)); polygon1.push_back(Point_2(0,2)); // Insert the constraint... CDT cdt; cdt.insert_constraint(polygon1.vertices_begin(), polygon1.vertices_end(), true); // ... and four points outside the box to create faces outside the domain cdt.insert(Point_2(-1,-1)); cdt.insert(Point_2(3,-1)); cdt.insert(Point_2(3,3)); cdt.insert(Point_2(-1,3)); // Refine the triangulation CGAL::refine_Delaunay_mesh_2(cdt, Mesh_2_criteria(0.125, 0.5)); CGAL::Random_points_in_triangle_mesh_2<Point_2, CDT> g(cdt); std::copy_n(g, 300, std::back_inserter(points)); for(std::size_t i=0; i<points.size(); ++i) { Point_2 p = points[i]; for(int j=0; j<2; ++j) { double coords[2] = {p.x(), p.y()}; if(coords[j] > 2.0 + eps || coords[j] < -eps) { std::cerr << "ERROR : Generated point (" << p << ") is not on a face of the domain." << std::endl; return 0; } } } return 1; }
int main(int argc, char ** argv) { if (argc != 5 && argc != 6) { fprintf(stderr, "usage: %s Host Port [Server] Method JSON\n", argv[0]); return EX_USAGE; } INT_32 iReturnCode = EX_SOFTWARE; try { CDT oRequest; CDT oResponse; if(argc == 5) { CTPP2JSONParser(oRequest).Parse(argv[4], argv[4] + strlen(argv[4])); ASXMLRPCClient oRPCClient(argv[1], atoi(argv[2]), 10000, 10000); oRPCClient.Call(argv[3], oRequest, oResponse); fprintf(stderr, "%s\n%s\n%s\n", argv[3], oRequest.Dump().c_str(), oResponse.Dump().c_str()); } else { CTPP2JSONParser(oRequest).Parse(argv[5], argv[5] + strlen(argv[5])); ASXMLRPCClient oRPCClient(argv[1], atoi(argv[2]), 1000, 1000, argv[3]); oRPCClient.Call(argv[4], oRequest, oResponse); fprintf(stderr, "%s\n%s\n%s\n", argv[4], oRequest.Dump().c_str(), oResponse.Dump().c_str()); } iReturnCode = EX_OK; } catch(STLW::exception &e) { fprintf(stderr, "ERROR: %s\n", e.what()); } fclose(stdin); fclose(stdout); fclose(stderr); return iReturnCode; }
INT_32 FormatString(const STLW::string & sFormatString, STLW::string & sResult, const CDT & oArgs) { using namespace CTPP; StringBuffer oBuffer(sResult); CCHAR_P sPos = sFormatString.data(); CCHAR_P sEnd = sFormatString.data() + sFormatString.size(); CCHAR_P sEndSave = sPos; UINT_32 iPos = 0; for(;;) { INT_32 iWidth = -1; INT_32 iPrecision = -1; CHAR_8 chPadSymbol = ' '; UINT_32 iFmtFlags = 0; eFmtLengths oFmtLengths = F_NONE; eParserState oParserState = C_INITIAL_STATE; // Find "%" at start of token while(sPos != sEnd) { if (*sPos == '%') { oParserState = C_START_FOUND; break; } ++sPos; } oBuffer.Append(sEndSave, sPos); if (oParserState == C_START_FOUND) { ++sPos; // Check end of string if (sPos == sEnd) { return -1; } bool bEndCycle = false; while (!bEndCycle) { // Flags switch(*sPos) { // '-' Left-justify within the given field width; Right justification is the default (see width sub-specifier). case '-': iFmtFlags |= F_LEFT_ALIGN; ++sPos; break; // '+' Forces to preceed the result with a plus or minus sign (+ or -) even for positive numbers. // By default, only negative numbers are preceded with a - sign. case '+': iFmtFlags |= F_FORCE_SIGN; iFmtFlags &= ~F_SIGN_SPACE; ++sPos; break; // ' ' (space) If no sign is going to be written, a blank space is inserted before the value. case ' ': iFmtFlags |= F_SIGN_SPACE; iFmtFlags &= ~F_FORCE_SIGN; ++sPos; break; // '#' Used with o, x or X specifiers the value is preceeded with 0, 0x or 0X respectively for values different than zero. // Used with e, E and f, it forces the written output to contain a decimal point even if no digits would follow. // By default, if no digits follow, no decimal point is written. // Used with g or G the result is the same as with e or E but trailing zeros are not removed. case '#': iFmtFlags |= F_HASH_SIGN; ++sPos; break; // '0' Left-pads the number with zeroes (0) instead of spaces, where padding is specified (see width sub-specifier). case '0': chPadSymbol = '0'; ++sPos; break; default: bEndCycle = true; break; } // Check end of string if (sPos == sEnd) { return -1; } } /* Width * number Minimum number of characters to be printed. If the value to be printed is shorter than this number, * the result is padded with blank spaces. The value is not truncated even if the result is larger. */ if (*sPos > '0' && *sPos <= '9') { iWidth = 0; while (sPos != sEnd && (*sPos >= '0' && *sPos <= '9')) { iWidth = iWidth * 10 + *sPos - '0'; ++sPos; } } /* * '*' The width is not specified in the format string, but as an additional integer value argument * preceding the argument that has to be formatted. */ else if (*sPos == '*') { iWidth = oArgs.GetCDT(iPos).GetInt(); ++iPos; ++sPos; } // Check end of string if (sPos == sEnd) { return -1; } // .precision if (*sPos == '.') { ++sPos; if (sPos == sEnd) { return -1; } iPrecision = 0; if (*sPos >= '0' && *sPos <= '9') { while (sPos != sEnd && (*sPos >= '0' && *sPos <= '9')) { iPrecision = iPrecision * 10 + *sPos - '0'; ++sPos; } } else if (*sPos == '*') { iPrecision = oArgs.GetCDT(iPos).GetInt(); ++iPos; ++sPos; } } // length switch(*sPos) { // h The argument is interpreted as a short int or unsigned short int (only applies to integer specifiers: i, d, o, u, x and X). case 'h': oFmtLengths = F_SHORT; ++sPos; break; // l The argument is interpreted as a long int or unsigned long int for integer specifiers (i, d, o, u, x and X), and as a wide character or wide character string for specifiers c and s. case 'l': // L The argument is interpreted as a long double (only applies to floating point specifiers: e, E, f, g and G). case 'L': { oFmtLengths = F_LONG; ++sPos; if (sPos == sEnd) { return -1; } if (*sPos == 'l' || *sPos == 'L') { oFmtLengths = F_LONG_LONG; ++sPos; } } break; } // Check end of string if (sPos == sEnd) { return -1; } // Specifiers // A % followed by another % character will write % to the string. if (*sPos == '%') { oBuffer.Append(sPos, 1); } else { const CDT oCurrentArgument = oArgs.GetCDT(iPos); ++iPos; switch(*sPos) { // Character 'a' case 'c': FmtChar(oBuffer, oCurrentArgument, iFmtFlags, iWidth, chPadSymbol); break; // 'd' or 'i' Signed decimal integer '392' case 'd': case 'i': FmtInt(oBuffer, oCurrentArgument, iFmtFlags, oFmtLengths, szDigitsLc, F_DECIMAL, 10, iWidth, iPrecision, chPadSymbol); break; // Scientific notation (mantise/exponent) using e character '3.9265e+2' case 'e': FmtSci(oBuffer, oCurrentArgument, iFmtFlags, oFmtLengths, 'e', iWidth, iPrecision, chPadSymbol); break; // Scientific notation (mantise/exponent) using E character '3.9265E+2' case 'E': FmtSci(oBuffer, oCurrentArgument, iFmtFlags, oFmtLengths, 'E', iWidth, iPrecision, chPadSymbol); break; // Decimal floating point '392.65' case 'f': FmtFloat(oBuffer, oCurrentArgument, iFmtFlags, oFmtLengths, 'e', F_FLOAT_F, iWidth, iPrecision, chPadSymbol); break; // Use the shorter of %e or %f '392.65' case 'g': FmtFloat(oBuffer, oCurrentArgument, iFmtFlags, oFmtLengths, 'e', F_FLOAT_G, iWidth, iPrecision, chPadSymbol); break; case 'F': FmtFloat(oBuffer, oCurrentArgument, iFmtFlags, oFmtLengths, 'E', F_FLOAT_F, iWidth, iPrecision, chPadSymbol); break; case 'G': FmtFloat(oBuffer, oCurrentArgument, iFmtFlags, oFmtLengths, 'E', F_FLOAT_G, iWidth, iPrecision, chPadSymbol); break; // Signed octal '610' case 'o': FmtInt(oBuffer, oCurrentArgument, iFmtFlags, oFmtLengths, szDigitsLc, F_OCTAL, 8, iWidth, iPrecision, chPadSymbol); break; // String of characters 'sample' case 's': FmtString(oBuffer, oCurrentArgument, iFmtFlags, iWidth, iPrecision, chPadSymbol); break; // Unsigned decimal integer '7235' case 'u': FmtInt(oBuffer, oCurrentArgument, iFmtFlags, oFmtLengths, szDigitsLc, F_UNSIGNED, 10, iWidth, iPrecision, chPadSymbol); break; // Unsigned hexadecimal integer '7fa' case 'x': FmtInt(oBuffer, oCurrentArgument, iFmtFlags, oFmtLengths, szDigitsLc, F_HEX, 16, iWidth, iPrecision, chPadSymbol); break; // Unsigned hexadecimal integer (capital letters) 7FA case 'X': FmtInt(oBuffer, oCurrentArgument, iFmtFlags, oFmtLengths, szDigitsUc, F_HEX, 16, iWidth, iPrecision, chPadSymbol); break; // Pointer address 1a2b3c4e case 'p': FmtInt(oBuffer, oCurrentArgument, iFmtFlags, oFmtLengths, szDigitsLc, F_POINTER, 16, iWidth, iPrecision, chPadSymbol); break; // Invalid format; return error code default: return -1; } ++sPos; } sEndSave = sPos; } if (sPos == sEnd) { break; } } oBuffer.Flush(); return 0; }
// // Floating point // static void FmtFloat(StringBuffer & oBuffer, const CDT & oCurrentArgument, const UINT_32 iFmtFlags, const eFmtLengths & oFmtLengths, const CHAR_8 chExponentSymbol, const eFmtSpecifier & oFmtSpecifier, INT_32 iWidth, INT_32 iPrecision, CHAR_8 chPadSymbol) { using namespace CTPP; /* * fF The double argument is rounded and converted to decimal notation * in the style [-]ddd.ddd, where the number of digits after the * decimal-point character is equal to the precision specification. * If the precision is missing, it is taken as 6; if the precision * is explicitly zero, no decimal-point character appears. If a * decimal point appears, at least one digit appears before it. * * gG The double argument is converted in style f or e (or F or E for G * conversions). The precision specifies the number of significant * digits. If the precision is missing, 6 digits are given; if the * precision is zero, it is treated as 1. Style e is used if the * exponent from its conversion is less than -4 or greater than or * equal to the precision. Trailing zeros are removed from the * fractional part of the result; a decimal point appears only if it * is followed by at least one digit. */ // if (iWidth == -1) { iWidth = 6; } INT_32 iMode; INT_32 iExponent = 0; INT_32 iSign = 0; CHAR_P szEnd = NULL; INT_32 iFormatPrecision; if (oFmtSpecifier == F_FLOAT_F) { iMode = 3; if (iPrecision == -1) { iPrecision = 6; } iFormatPrecision = iPrecision; } // Only one decision left else /* if (oFmtSpecifier == F_FLOAT_G) */ { iMode = 2; if (iPrecision == -1) { iPrecision = 6; } else if (iPrecision == 0) { iPrecision = 1; } iFormatPrecision = iPrecision + 1; } Bigint *freelist[Kmax+1]; for (UINT_32 iPos = 0; iPos <= Kmax; ++iPos) { freelist[iPos] = NULL; } W_FLOAT dData = oCurrentArgument.GetFloat(); AllocatedBlock * aBlocks = NULL; CHAR_P szBuffer = ctpp_dtoa(&aBlocks, freelist, dData, iMode, iFormatPrecision, &iExponent, &iSign, &szEnd); bool bIsNegative = iSign < 0; --iExponent; INT_32 iPos = szEnd - szBuffer; // Data length INT_32 iFormattedLength; if (oFmtSpecifier == F_FLOAT_F) { if (iExponent < 0) { iFormattedLength = iPrecision + 2; } else { iFormattedLength = iPrecision + iExponent + 1; } } else /* if (oFmtSpecifier == F_FLOAT_G) */ { /* * Style e is used if the * exponent from its conversion is less than -4 or greater than or * equal to the precision. */ if (iExponent < -4 || iExponent >= iPrecision) { // Free memory freedtoa(&aBlocks); if (iWidth == -1) { iWidth = 6; } FmtSci(oBuffer, oCurrentArgument, iFmtFlags, oFmtLengths, chExponentSymbol, iWidth, iPrecision, chPadSymbol); return; } if (iPos > iPrecision) { iPos = iPrecision; } else { iPrecision = iPos; } iFormattedLength = iPrecision; if (iExponent < 0) { iFormattedLength += 1 - iExponent; } } // Sign? if (bIsNegative || iFmtFlags & (F_FORCE_SIGN | F_SIGN_SPACE)) { ++iFormattedLength; } // Right-aligned if ((iFmtFlags & F_LEFT_ALIGN) != F_LEFT_ALIGN) { // Spaces, if need if (iWidth > iFormattedLength) { oBuffer.Append(iWidth - iFormattedLength, ' '); } } // Sign if (bIsNegative) { oBuffer.Append(1, '-'); } else if (iFmtFlags & F_FORCE_SIGN) { oBuffer.Append(1, '+'); } else if (iFmtFlags & F_SIGN_SPACE) { oBuffer.Append(1, ' '); } if (oFmtSpecifier == F_FLOAT_F) { // Value if (iExponent < 0) { const INT_32 iChars = iPrecision + iExponent + 1; oBuffer.Append(1, '0'); oBuffer.Append(1, '.'); oBuffer.Append(-iExponent - 1, '0'); if (iChars > iPos) { oBuffer.Append(szBuffer, iPos); oBuffer.Append(iChars - iPos, '0'); } else { oBuffer.Append(szBuffer, iChars); } } else { // Value oBuffer.Append(szBuffer, iExponent + 1); if (iPrecision > 0) { iPos -= iExponent; oBuffer.Append(1, '.'); oBuffer.Append(szBuffer + iExponent + 1, iPos - 1); if (iPrecision + 1 > iPos) { oBuffer.Append(iPrecision - iPos + 1, '0'); } } } } else /* if (oFmtSpecifier == F_FLOAT_G) */ { // Value if (iExponent < 0) { const INT_32 iChars = (iPrecision < iPos) ? iPrecision : iPos; oBuffer.Append(1, '0'); oBuffer.Append(1, '.'); oBuffer.Append(- iExponent - 1, '0'); oBuffer.Append(szBuffer, iChars); } else { oBuffer.Append(szBuffer, iExponent + 1); if (iPos > iExponent + 1) { oBuffer.Append(1, '.'); oBuffer.Append(szBuffer + iExponent + 1, iPrecision - iExponent - 1); } } } // Free memory freedtoa(&aBlocks); // Left-aligned if ((iFmtFlags & F_LEFT_ALIGN) == F_LEFT_ALIGN) { // Spaces, if need if (iWidth > iFormattedLength) { oBuffer.Append(iWidth - iFormattedLength, ' '); } } }
// // Scientific // static void FmtSci(StringBuffer & oBuffer, const CDT & oCurrentArgument, const UINT_32 iFmtFlags, const eFmtLengths & oFmtLengths, const CHAR_8 chExponentSymbol, INT_32 iWidth, INT_32 iPrecision, CHAR_8 chPadSymbol) { using namespace CTPP; /* * eE The double argument is rounded and converted in the style * [-]d.ddde+-dd where there is one digit before the decimal-point * character and the number of digits after it is equal to the pre- * cision; if the precision is missing, it is taken as 6; if the * precision is zero, no decimal-point character appears. An E con- * version uses the letter `E' (rather than `e') to introduce the * exponent. The exponent always contains at least two digits; if * the value is zero, the exponent is 00. */ if (iPrecision == -1) { iPrecision = 6; } if (iWidth == -1) { iWidth = 6; } const INT_32 iMode = 2; INT_32 iExponent = 0; INT_32 iSign = 0; CHAR_P szEnd = NULL; Bigint *freelist[Kmax+1]; for (UINT_32 iPos = 0; iPos <= Kmax; ++iPos) { freelist[iPos] = NULL; } W_FLOAT dData = oCurrentArgument.GetFloat(); AllocatedBlock * aBlocks = NULL; CHAR_P szBuffer = ctpp_dtoa(&aBlocks, freelist, dData, iMode, iPrecision, &iExponent, &iSign, &szEnd); bool bIsNegative = iSign < 0; --iExponent; // Format Exponent CHAR_8 szExponentBuffer[C_INT_BUFFER_LEN + 1]; szExponentBuffer[C_INT_BUFFER_LEN] = 0; bool bExponentIsNegative = false; // Signed INT_32 iExponentPos = DoFormat<INT_32>(iExponent, 10, szDigitsUc, szExponentBuffer, bExponentIsNegative); // Atleast 2 digits in exponent if (iExponentPos == 1) { iExponentPos = 2; szExponentBuffer[C_INT_BUFFER_LEN - 2] = '0'; } ++iExponentPos; // Add exponent sign szExponentBuffer[C_INT_BUFFER_LEN - iExponentPos] = bExponentIsNegative ? '-' : '+'; // Add exponent char ++iExponentPos; szExponentBuffer[C_INT_BUFFER_LEN - iExponentPos] = chExponentSymbol; INT_32 iPos = szEnd - szBuffer; // Data length INT_32 iFormattedLength = iExponentPos + 1; //;// = iPos + iExponentPos + 1; // Precision if (iPrecision > iPos) { //iFormattedLength += (iPrecision - iPos); iFormattedLength += iPrecision; } else { iPos = iPrecision; iFormattedLength += iPos; } // Sign? if (bIsNegative || iFmtFlags & (F_FORCE_SIGN | F_SIGN_SPACE)) { ++iFormattedLength; } // Right-aligned if ((iFmtFlags & F_LEFT_ALIGN) != F_LEFT_ALIGN) { // Spaces, if need if (iWidth > iFormattedLength) { oBuffer.Append(iWidth - iFormattedLength, ' '); } } // Sign if (bIsNegative) { oBuffer.Append(1, '-'); } else if (iFmtFlags & F_FORCE_SIGN) { oBuffer.Append(1, '+'); } else if (iFmtFlags & F_SIGN_SPACE) { oBuffer.Append(1, ' '); } // Value oBuffer.Append(szBuffer, 1); oBuffer.Append(1, '.'); oBuffer.Append(szBuffer + 1, iPos - 1); // Free memory freedtoa(&aBlocks); // Zeroes, if need if (iPrecision > iPos) { oBuffer.Append(iPrecision - iPos, '0'); } // Exponent oBuffer.Append(szExponentBuffer + C_INT_BUFFER_LEN - iExponentPos, iExponentPos); // Left-aligned if ((iFmtFlags & F_LEFT_ALIGN) == F_LEFT_ALIGN) { // Spaces, if need if (iWidth > iFormattedLength) { oBuffer.Append(iWidth - iFormattedLength, ' '); } } }
// // Integer // static void FmtInt(StringBuffer & oBuffer, const CDT & oCurrentArgument, const UINT_32 iFmtFlags, const eFmtLengths & oFmtLengths, CCHAR_P szDigits, const eFmtSpecifier & oFmtSpecifier, const INT_32 iRadix, INT_32 iWidth, INT_32 iPrecision, CHAR_8 chPadSymbol) { if (iWidth < 0) { iWidth = 0; } if (iPrecision < 0) { iPrecision = 0; } CHAR_8 szBuffer[C_INT_BUFFER_LEN + 1]; szBuffer[C_INT_BUFFER_LEN] = 0; INT_32 iPos = 0; bool bIsNegative = false; // Signed if (oFmtSpecifier == F_DECIMAL) { switch (oFmtLengths) { case F_NONE: case F_LONG: iPos = DoFormat<INT_32>(oCurrentArgument.GetInt(), iRadix, szDigits, szBuffer, bIsNegative); break; case F_SHORT: iPos = DoFormat<INT_16>(oCurrentArgument.GetInt(), iRadix, szDigits, szBuffer, bIsNegative); break; case F_LONG_LONG: iPos = DoFormat<INT_64>(oCurrentArgument.GetInt(), iRadix, szDigits, szBuffer, bIsNegative); break; } } // Unsigned, hex, octal else { switch (oFmtLengths) { case F_NONE: case F_LONG: iPos = DoFormat<UINT_32>(oCurrentArgument.GetInt(), iRadix, szDigits, szBuffer, bIsNegative); break; case F_SHORT: iPos = DoFormat<UINT_16>(oCurrentArgument.GetInt(), iRadix, szDigits, szBuffer, bIsNegative); break; case F_LONG_LONG: iPos = DoFormat<UINT_64>(oCurrentArgument.GetInt(), iRadix, szDigits, szBuffer, bIsNegative); break; } } UINT_32 iBufferPos = C_INT_BUFFER_LEN - iPos; // Left-aligned output if (iFmtFlags & F_LEFT_ALIGN || chPadSymbol == '0') { // Sign if (bIsNegative) { oBuffer.Append(1, '-'); --iWidth; } else if (iFmtFlags & F_FORCE_SIGN) { oBuffer.Append(1, '+'); --iWidth; } else if (iFmtFlags & F_SIGN_SPACE) { oBuffer.Append(1, ' '); --iWidth; } // Hash if (iFmtFlags & F_HASH_SIGN) { if (oFmtSpecifier == F_OCTAL) { oBuffer.Append(1, '0'); } else if (oFmtSpecifier == F_HEX || oFmtSpecifier == F_POINTER) { oBuffer.Append(1, '0'); oBuffer.Append(1, szDigits[16]); } } // Zeroes, if need if (iPrecision > iPos) { iWidth -= (iPrecision - iPos); oBuffer.Append(iPrecision - iPos, '0'); } if (chPadSymbol == '0') { // Spaces, if need if (iWidth > iPos) { oBuffer.Append(iWidth - iPos, '0'); } // Value oBuffer.Append(szBuffer + iBufferPos, iPos); } else { // Value oBuffer.Append(szBuffer + iBufferPos, iPos); // Spaces, if need if (iWidth > iPos) { oBuffer.Append(iWidth - iPos, ' '); } } return; } // Right-aligned INT_32 iFormattedLength = iPos; // Precision if (iPrecision > iPos) { iFormattedLength += (iPrecision - iPos); } // Sign? if (bIsNegative || iFmtFlags & (F_FORCE_SIGN | F_SIGN_SPACE)) { ++iFormattedLength; } // Hash if (iFmtFlags & F_HASH_SIGN) { if (oFmtSpecifier == F_OCTAL) { ++iFormattedLength; } else if (oFmtSpecifier == F_HEX || oFmtSpecifier == F_POINTER) { iFormattedLength += 2; } } // Spaces, if need if (iWidth > iFormattedLength) { oBuffer.Append(iWidth - iFormattedLength, ' '); } // Sign if (bIsNegative) { oBuffer.Append(1, '-'); --iWidth; } else if (iFmtFlags & F_FORCE_SIGN) { oBuffer.Append(1, '+'); --iWidth; } else if (iFmtFlags & F_SIGN_SPACE) { oBuffer.Append(1, ' '); --iWidth; } // Hash if (iFmtFlags & F_HASH_SIGN) { if (oFmtSpecifier == F_OCTAL) { oBuffer.Append(1, '0'); } else if (oFmtSpecifier == F_HEX || oFmtSpecifier == F_POINTER) { oBuffer.Append(1, '0'); oBuffer.Append(1, szDigits[16]); } } if (iPrecision > iPos) { oBuffer.Append(iPrecision - iPos, '0'); } // Value oBuffer.Append(szBuffer + iBufferPos, iPos); }
int main() { typedef viennagrid::plc_2d_mesh mesh_type; mesh_type mesh; typedef viennagrid::result_of::point<mesh_type>::type point_type; typedef viennagrid::result_of::element<mesh_type, viennagrid::vertex_tag>::type vertex_type; typedef viennagrid::result_of::handle<mesh_type, viennagrid::vertex_tag>::type vertex_handle_type; typedef viennagrid::result_of::element<mesh_type, viennagrid::line_tag>::type line_type; typedef viennagrid::result_of::handle<mesh_type, viennagrid::line_tag>::type line_handle_type; typedef viennagrid::result_of::element<mesh_type, viennagrid::plc_tag>::type plc_type; typedef viennagrid::result_of::handle<mesh_type, viennagrid::plc_tag>::type plc_handle_type; plc_handle_type plc_handle; { std::vector<vertex_handle_type> v; v.push_back( viennagrid::make_vertex( mesh, point_type(0, 0) ) ); v.push_back( viennagrid::make_vertex( mesh, point_type(10, 0) ) ); v.push_back( viennagrid::make_vertex( mesh, point_type(20, 10) ) ); v.push_back( viennagrid::make_vertex( mesh, point_type(20, 20) ) ); v.push_back( viennagrid::make_vertex( mesh, point_type(10, 20) ) ); v.push_back( viennagrid::make_vertex( mesh, point_type(0, 10) ) ); v.push_back( viennagrid::make_vertex( mesh, point_type(5, 5) ) ); v.push_back( viennagrid::make_vertex( mesh, point_type(10, 10) ) ); v.push_back( viennagrid::make_vertex( mesh, point_type(12, 10) ) ); v.push_back( viennagrid::make_vertex( mesh, point_type(10, 12) ) ); v.push_back( viennagrid::make_vertex( mesh, point_type(8, 10) ) ); v.push_back( viennagrid::make_vertex( mesh, point_type(15, 15) ) ); std::vector<line_handle_type> lines; { std::vector<vertex_handle_type>::iterator start = v.begin(); std::vector<vertex_handle_type>::iterator end = v.begin() + 7; std::vector<vertex_handle_type>::iterator it1 = start; std::vector<vertex_handle_type>::iterator it2 = it1; ++it2; for (; it2 != end; ++it1, ++it2) lines.push_back( viennagrid::make_line(mesh, *it1, *it2) ); lines.push_back( viennagrid::make_line(mesh, *it1, *start) ); } { std::vector<vertex_handle_type>::iterator start = v.begin() + 7; std::vector<vertex_handle_type>::iterator end = v.begin() + 10; std::vector<vertex_handle_type>::iterator it1 = start; std::vector<vertex_handle_type>::iterator it2 = it1; ++it2; for (; it2 != end; ++it1, ++it2) lines.push_back( viennagrid::make_line(mesh, *it1, *it2) ); lines.push_back( viennagrid::make_line(mesh, *it1, *start) ); } lines.push_back( viennagrid::make_element<line_type>( mesh, v.begin() + 9, v.begin() + 11 ) ); vertex_handle_type point = v[11]; std::vector<point_type> hole_points; hole_points.push_back( point_type(10.5, 10.5) ); plc_handle = viennagrid::make_plc( mesh, lines.begin(), lines.end(), &point, &point + 1, hole_points.begin(), hole_points.end() ); } plc_type & plc = viennagrid::dereference_handle(mesh, plc_handle); typedef viennagrid::result_of::element_range<plc_type, viennagrid::vertex_tag>::type vertex_range_type; typedef viennagrid::result_of::iterator<vertex_range_type>::type vertex_range_iterator; typedef viennagrid::result_of::element_range<plc_type, viennagrid::line_tag>::type line_range_type; typedef viennagrid::result_of::iterator<line_range_type>::type line_range_iterator; typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; typedef CGAL::Triangulation_vertex_base_2<Kernel> VertexBase; typedef CGAL::Delaunay_mesh_face_base_2<Kernel> FaceBase; typedef CGAL::Triangulation_data_structure_2<VertexBase, FaceBase> Triangulation_structure; typedef CGAL::Constrained_Delaunay_triangulation_2<Kernel, Triangulation_structure> CDT; typedef CGAL::Delaunay_mesh_size_criteria_2<CDT> Criteria; typedef CDT::Vertex_handle Vertex_handle; typedef CDT::Point Point; CDT cdt; std::map<vertex_handle_type, Vertex_handle> vertex_handle_map; vertex_range_type vertices = viennagrid::elements<viennagrid::vertex_tag>(plc); for (vertex_range_iterator it = vertices.begin(); it != vertices.end(); ++it) { vertex_handle_type const & vtx_handle = it.handle(); vertex_type const & vtx = *it; point_type const & vgrid_point = viennagrid::point( mesh, vtx ); Vertex_handle handle = cdt.insert( Point(vgrid_point[0], vgrid_point[1]) ); vertex_handle_map[vtx_handle] = handle; } line_range_type lines = viennagrid::elements<viennagrid::line_tag>(plc); for (line_range_iterator it = lines.begin(); it != lines.end(); ++it) { line_type & line = *it; vertex_handle_type vgrid_v0 = viennagrid::elements<viennagrid::vertex_tag>(line).handle_at(0); vertex_handle_type vgrid_v1 = viennagrid::elements<viennagrid::vertex_tag>(line).handle_at(1); Vertex_handle cgal_v0 = vertex_handle_map[vgrid_v0]; Vertex_handle cgal_v1 = vertex_handle_map[vgrid_v1]; cdt.insert_constraint(cgal_v0, cgal_v1); } std::vector<point_type> & vgrid_list_of_holes = viennagrid::hole_points(plc); std::list<Point> cgal_list_of_holes; for (std::vector<point_type>::iterator it = vgrid_list_of_holes.begin(); it != vgrid_list_of_holes.end(); ++it) cgal_list_of_holes.push_back( Point( (*it)[0], (*it)[1] ) ); CGAL::refine_Delaunay_mesh_2(cdt, cgal_list_of_holes.begin(), cgal_list_of_holes.end(), Criteria()); std::cout << "Number of vertices: " << cdt.number_of_vertices() << std::endl; std::cout << "Number of finite faces: " << cdt.number_of_faces() << std::endl; typedef viennagrid::triangular_2d_mesh triangle_mesh_type; triangle_mesh_type triangle_mesh; typedef viennagrid::result_of::point<triangle_mesh_type>::type triangle_point_type; typedef viennagrid::result_of::element<triangle_mesh_type, viennagrid::vertex_tag>::type triangle_vertex_type; typedef viennagrid::result_of::handle<triangle_mesh_type, viennagrid::vertex_tag>::type triangle_vertex_handle_type; typedef viennagrid::result_of::element<triangle_mesh_type, viennagrid::line_tag>::type triangle_line_type; typedef viennagrid::result_of::handle<triangle_mesh_type, viennagrid::line_tag>::type triangle_line_handle_type; typedef viennagrid::result_of::element<triangle_mesh_type, viennagrid::triangle_tag>::type triangle_triangle_type; typedef viennagrid::result_of::handle<triangle_mesh_type, viennagrid::triangle_tag>::type triangle_triangle__handle_type; std::map<Point, triangle_vertex_handle_type> points; int mesh_faces_counter = 0; for(CDT::Finite_faces_iterator fit = cdt.finite_faces_begin(); fit != cdt.finite_faces_end(); ++fit) { if(fit->is_in_domain()) { typedef CDT::Triangle Triangle; Triangle tri = cdt.triangle(fit); triangle_vertex_handle_type vgrid_vtx[3]; for (int i = 0; i < 3; ++i) { std::map<Point, triangle_vertex_handle_type>::iterator pit = points.find( tri[i] ); if (pit == points.end()) { vgrid_vtx[i] = viennagrid::make_vertex( triangle_mesh, triangle_point_type(tri[i].x(), tri[i].y()) ); points[ tri[i] ] = vgrid_vtx[i]; } else vgrid_vtx[i] = pit->second; } viennagrid::make_element<triangle_triangle_type>( triangle_mesh, vgrid_vtx, vgrid_vtx+3 ); std::cout << tri << std::endl; ++mesh_faces_counter; } } std::cout << "Number of faces in the mesh mesh: " << mesh_faces_counter << std::endl; std::copy( viennagrid::elements<triangle_triangle_type>(triangle_mesh).begin(), viennagrid::elements<triangle_triangle_type>(triangle_mesh).end(), std::ostream_iterator<triangle_triangle_type>(std::cout, "\n") ); viennagrid::io::vtk_writer<triangle_mesh_type> vtk_writer; vtk_writer(triangle_mesh, "test"); }
CDT Chop(CDT& a) { return CDT(Chop(a.real()), Chop(a.imag())); }
void FixedPlaneMesh::TrianglatePolygon(const double3& normal, std::vector<Point3D>& pts, ListOfvertices& results) { if (pts.size() < 3) return ; if (pts.size() ==3) { VertexInfo vi1(pts[0], normal, mColor); VertexInfo vi2(pts[1], normal, mColor); VertexInfo vi3(pts[2], normal, mColor); results.push_back(vi1); results.push_back(vi2); results.push_back(vi3); return ; } typedef CGAL::Exact_predicates_inexact_constructions_kernel K; typedef CGAL::Triangulation_vertex_base_2<K> Vb; typedef CGAL::Constrained_triangulation_face_base_2<K> Fb; typedef CGAL::Triangulation_data_structure_2<Vb,Fb> TDS; //typedef CGAL::Exact_predicates_tag Itag; typedef CGAL::Constrained_Delaunay_triangulation_2<K, TDS, CGAL::No_intersection_tag> CDT; vec3<double> origin = pts[0]; vec3<double> N = normal; vec3<double> U = normalize(pts[1] - origin); vec3<double> V = cross(N, U); CDT cdt; CDT::Vertex_handle vh1, vh2, vh3; vec3<double> v0 = PosToLocal(U, V, N, origin, pts[0]); CDT::Point p0(v0.x, v0.y); vh1 = vh3 = cdt.insert(p0); for ( int i = 1; i< pts.size() ; i++) { vec3<double> v1 = PosToLocal(U, V, N, origin, pts[i]); CDT::Point p1(v1.x, v1.y); vh2 = cdt.insert(p1); cdt.insert_constraint(vh1, vh2); vh1 = vh2; } cdt.insert_constraint(vh2, vh3); int count = cdt.number_of_faces() ; results.reserve(count*3); for (CDT::Finite_faces_iterator fit = cdt.finite_faces_begin(); fit != cdt.finite_faces_end(); ++fit) { vec2<double> v0(fit->vertex(2)->point().x(),fit->vertex(2)->point().y() ); vec2<double> v1(fit->vertex(1)->point().x(),fit->vertex(1)->point().y() ); vec2<double> v2(fit->vertex(0)->point().x(),fit->vertex(0)->point().y() ); if (IsEqual(cross(v0- v2, v1-v2), (double)0., (double)EPSF )) continue; // vec3<double > p0(v0, 0.0); vec3<double > p1(v1, 0.0); vec3<double > p2(v2, 0.0); p0 = PosToGlobal(U, V, N, origin, p0); p1 = PosToGlobal(U, V, N, origin, p1); p2 = PosToGlobal(U, V, N, origin, p2); VertexInfo vi1(p0, N, mColor); VertexInfo vi2(p1, N, mColor); VertexInfo vi3(p2, N, mColor); results.push_back(vi1); results.push_back(vi2); results.push_back(vi3); } }
bool Delaunay2dMesh::buildMesh( const std::vector<CCVector2>& points2D, const std::vector<int>& segments2D, char* outputErrorStr/*=0*/) { #if defined(USE_TRIANGLE_LIB) //we use the external library 'Triangle' triangulateio in; memset(&in,0,sizeof(triangulateio)); in.numberofpoints = static_cast<int>(points2D.size()); in.pointlist = (REAL*)(&points2D[0]); in.segmentlist = (int*)(&segments2D[0]); assert((segments2D.size() & 1) == 0); in.numberofsegments = static_cast<int>(segments2D.size()/2); triangulateio out; memset(&out,0,sizeof(triangulateio)); try { triangulate ( "pczBPNIOQY", &in, &out, 0 ); } catch (std::exception& e) { if (outputErrorStr) strcpy(outputErrorStr,e.what()); return false; } catch (...) { if (outputErrorStr) strcpy(outputErrorStr,"Unknown error"); return false; } m_numberOfTriangles = out.numberoftriangles; if (m_numberOfTriangles > 0) { m_triIndexes = out.trianglelist; //remove non existing points int* _tri = out.trianglelist; for (int i=0; i<out.numberoftriangles; ) { if ( _tri[0] >= in.numberofpoints || _tri[1] >= in.numberofpoints || _tri[2] >= in.numberofpoints) { int lasTriIndex = (out.numberoftriangles-1) * 3; _tri[0] = out.trianglelist[lasTriIndex + 0]; _tri[1] = out.trianglelist[lasTriIndex + 1]; _tri[2] = out.trianglelist[lasTriIndex + 2]; --out.numberoftriangles; } else { _tri += 3; ++i; } } //Reduce memory size if (out.numberoftriangles < static_cast<int>(m_numberOfTriangles)) { assert(out.numberoftriangles > 0); realloc(m_triIndexes, sizeof(int)*out.numberoftriangles*3); m_numberOfTriangles = out.numberoftriangles; } } trifree(out.segmentmarkerlist); trifree(out.segmentlist); m_globalIterator = m_triIndexes; m_globalIteratorEnd = m_triIndexes + 3*m_numberOfTriangles; return true; #elif defined(USE_CGAL_LIB) //CGAL boilerplate typedef CGAL::Exact_predicates_inexact_constructions_kernel K; //We define a vertex_base with info. The "info" (size_t) allow us to keep track of the original point index. typedef CGAL::Triangulation_vertex_base_with_info_2<size_t, K> Vb; typedef CGAL::Constrained_triangulation_face_base_2<K> Fb; typedef CGAL::No_intersection_tag Itag; //This tag could ben changed if we decide to handle intersection typedef CGAL::Triangulation_data_structure_2<Vb, Fb> Tds; typedef CGAL::Constrained_Delaunay_triangulation_2<K, Tds, Itag> CDT; typedef CDT::Point cgalPoint; std::vector< std::pair<cgalPoint, size_t > > constraints; size_t constrCount = segments2D.size(); try { constraints.reserve(constrCount); } catch (const std::bad_alloc&) { if (outputErrorStr) strcpy(outputErrorStr, "Not enough memory"); return false; }; //We create the Constrained Delaunay Triangulation (CDT) CDT cdt; //We build the constraints for(size_t i = 0; i < constrCount; ++i) { const CCVector2 * pt = &points2D[segments2D[i]]; constraints.push_back(std::make_pair(cgalPoint(pt->x, pt->y), segments2D[i])); } //The CDT is built according to the constraints cdt.insert(constraints.begin(), constraints.end()); m_numberOfTriangles = static_cast<unsigned >(cdt.number_of_faces()); m_triIndexes = new int[cdt.number_of_faces()*3]; //The cgal data structure is converted into CC one if (m_numberOfTriangles > 0) { int faceCount = 0; for (CDT::Face_iterator face = cdt.faces_begin(); face != cdt.faces_end(); ++face, faceCount+=3) { m_triIndexes[0+faceCount] = static_cast<int>(face->vertex(0)->info()); m_triIndexes[1+faceCount] = static_cast<int>(face->vertex(1)->info()); m_triIndexes[2+faceCount] = static_cast<int>(face->vertex(2)->info()); }; } m_globalIterator = m_triIndexes; m_globalIteratorEnd = m_triIndexes + 3*m_numberOfTriangles; return true; #else if (outputErrorStr) strcpy(outputErrorStr, "Triangle library not supported"); return false; #endif }
void triangulate(const Polygon_2& polygon, Cut_iter cuts_begin, Cut_iter cuts_end, const boost::unordered_map<Point_3, boost::unordered_set<Segment_3_undirected> >& point2edges, Out_iter triangles) { typedef CGAL::Triangulation_vertex_base_2<Kernel> Vb; typedef CGAL::Triangulation_vertex_base_with_info_2<Point_3, Kernel, Vb> Info; typedef CGAL::Constrained_triangulation_face_base_2<Kernel> Fb; typedef CGAL::Triangulation_data_structure_2<Info,Fb> TDS; typedef CGAL::Exact_predicates_tag Itag; typedef CGAL::Constrained_Delaunay_triangulation_2<Kernel, TDS, Itag> CDT; typedef CDT::Vertex_handle Vertex_handle; static log4cplus::Logger logger = log4cplus::Logger::getInstance("polygon_utils"); Polygon_2 p(polygon); LOG4CPLUS_TRACE(logger, "Triangulating " << pp(p)); if (p.size() < 3) return; bool vertical = is_vertical(p); if (vertical) { LOG4CPLUS_TRACE(logger, "Polygon is vertical. Rotating."); p = yz_swap_neg(p); } bool reverse = !p.is_counterclockwise_oriented(); if (reverse) p.reverse_orientation(); CDT cdt; boost::unordered_map<Point_3, Vertex_handle> point2handle; for (Polygon_2::Vertex_iterator it = p.vertices_begin(); it != p.vertices_end(); ++it) { Vertex_handle h = cdt.insert(*it); point2handle[*it] = h; h->info() = *it;//it->z(); } Polygon_2::Vertex_circulator start = p.vertices_circulator(); Polygon_2::Vertex_circulator c = start; Polygon_2::Vertex_circulator n = c; ++n; do { Vertex_handle ch = point2handle[*c];//cdt.insert(*c); Vertex_handle nh = point2handle[*n];//cdt.insert(*n); // ch->info() = c->z(); // nh->info() = n->z(); // cdt.insert_constraint(*c, *n); cdt.insert_constraint(ch, nh); ++c; ++n; } while (c != start); for (Cut_iter c_it = cuts_begin; c_it != cuts_end; ++c_it) { Polyline_2 cut = *c_it; LOG4CPLUS_TRACE(logger, "Adding cut: " << pp(cut)); if (vertical) cut = yz_swap_neg(cut); for (Polyline_2::const_iterator c = cut.begin(); c != cut.end(); ++c) { Polyline_2::const_iterator n = c; ++n; if (n != cut.end()) { const Point_3& cp = *c; const Point_3& np = *n; if (point2handle.find(cp) == point2handle.end()) { Vertex_handle h = cdt.insert(cp); point2handle[cp] = h; h->info() = cp;//cp.z(); } if (point2handle.find(np) == point2handle.end()) { Vertex_handle h = cdt.insert(np); point2handle[np] = h; h->info() = np;//np.z(); } Vertex_handle ch = point2handle[*c];//cdt.insert(*c); Vertex_handle nh = point2handle[*n];//cdt.insert(*n); // ch->info() = c->z(); // nh->info() = n->z(); // cdt.insert_constraint(*c, *n); cdt.insert_constraint(ch, nh); LOG4CPLUS_TRACE(logger, " " << pp(Segment_2(*c, *n))); } } } // Loop through the triangulation and store the vertices of each triangle for (CDT::Finite_faces_iterator ffi = cdt.finite_faces_begin(); ffi != cdt.finite_faces_end(); ++ffi) { Triangle t; Point_3 center = centroid(ffi->vertex(0)->info(), ffi->vertex(1)->info(), ffi->vertex(2)->info()); if (p.has_on_bounded_side(center) && is_legal(ffi->vertex(0)->info(), ffi->vertex(1)->info(), ffi->vertex(2)->info(), point2edges)) { for (int i = 0; i < 3; ++i) { int idx = reverse ? 2-i : i; if (!vertical) { // Point_3 p(ffi->vertex(i)->point()); // p = Point_3(p.x(), p.y(), ffi->vertex(i)->info()); Point_3 p(ffi->vertex(i)->info()); t[idx] = p; } else { // Point_3 p(ffi->vertex(i)->point()); // p = Point_3(p.x(), p.y(), ffi->vertex(i)->info()); Point_3 p(ffi->vertex(i)->info()); t[idx] = yz_swap_pos(p); } } LOG4CPLUS_TRACE(logger, "Adding tile: " << pp_tri(t)); *triangles++ = t; } } }
void triangulate(const Polygon& polygon, Triangle_iter triangles, const boost::unordered_map<Point_3, boost::unordered_set<Segment_3_undirected> >& point2edges) { typedef CGAL::Triangulation_vertex_base_2<Kernel> Vb; typedef CGAL::Triangulation_vertex_base_with_info_2<bool, Kernel, Vb> Info; typedef CGAL::Constrained_triangulation_face_base_2<Kernel> Fb; typedef CGAL::Triangulation_data_structure_2<Info,Fb> TDS; typedef CGAL::Exact_predicates_tag Itag; typedef CGAL::Constrained_Delaunay_triangulation_2<Kernel, TDS, Itag> CDT; static log4cplus::Logger tlogger = log4cplus::Logger::getInstance("polygon_utils"); LOG4CPLUS_TRACE(tlogger, "Triangulating " << pp(polygon)); if (polygon.size() < 3) return; Polygon p = polygon; bool vertical = is_vertical(p); if (vertical) { LOG4CPLUS_TRACE(tlogger, "Polygon is vertical. Rotating."); p = yz_swap_neg(p); } bool reverse = !p.is_counterclockwise_oriented(); // THIS IS BAD, BAD, BAD! { typename Polygon::Vertex_circulator start = p.vertices_circulator(); typename Polygon::Vertex_circulator c = start; typename Polygon::Vertex_circulator n = c; typename Polygon::Vertex_circulator prev = c; ++n; --prev; Polygon_2 newp; do { if (!CGAL::collinear(*prev, *c, *n)) newp.push_back(*c); ++prev; ++c; ++n; } while (c != start); p = newp; } CDT cdt; typename Polygon::Vertex_circulator start = p.vertices_circulator(); typename Polygon::Vertex_circulator c = start; typename Polygon::Vertex_circulator n = c; do { cdt.insert_constraint(*c, *n); ++c; ++n; } while (c != start); // Loop through the triangulation and store the vertices of each triangle for (CDT::Finite_faces_iterator ffi = cdt.finite_faces_begin(); ffi != cdt.finite_faces_end(); ++ffi) { Triangle t; Point_3 center = centroid(ffi->vertex(0)->point(), ffi->vertex(1)->point(), ffi->vertex(2)->point()); if (p.has_on_bounded_side(center) && is_legal(ffi->vertex(0)->point(), ffi->vertex(1)->point(), ffi->vertex(2)->point(), point2edges)) { for (int i = 0; i < 3; ++i) { int idx = reverse ? 2-i : i; if (!vertical) t[idx] = ffi->vertex(i)->point(); else t[idx] = yz_swap_pos(ffi->vertex(i)->point()); } LOG4CPLUS_TRACE(tlogger, "Adding tile: " << pp_tri(t)); *triangles = t; ++triangles; } } }
void convert_to_dealii_format(CDT &cdt, dealii::Triangulation<2> &triangulation) { std::vector<dealii::Point<2> > vertex_in_grid; std::vector<dealii::CellData<2> > cell_in_grid; for(auto fit = cdt.finite_faces_begin(); fit != cdt.finite_faces_end(); ++fit) { CDT::Triangle trg = cdt.triangle(fit); // location of points on the triangle // // 2 // / \ // / \ // / \ // / \ // 5 / \ 4 // /\ /\ // / \ / \ // / \ / \ // / \ / \ // / 6 \ // / | \ // / | \ // / | \ // 0___________________________1 // 3 // dealii::Point<2> p[7] = { dealii::Point<2>(trg[0].x(), trg[0].y()), dealii::Point<2>(trg[1].x(), trg[1].y()), dealii::Point<2>(trg[2].x(), trg[2].y()), (p[0] + p[1]) / 2.0, (p[1] + p[2]) / 2.0, (p[2] + p[0]) / 2.0, (p[0] + p[1] + p[2]) / 3.0 }; struct IndexPoint { u32 index; bool point_already_exist = false; }; IndexPoint index_point[7]; FOR(i, 0, 7) FOR(j, 0, vertex_in_grid.size()) if (p[i].distance (vertex_in_grid[j]) < 1.e-10) { index_point[i].index = j; index_point[i].point_already_exist = true; }; FOR(i, 0, 7) if (not index_point[i].point_already_exist) { vertex_in_grid .push_back (p[i]); index_point[i].index = vertex_in_grid.size() - 1; index_point[i].point_already_exist = true; }; u8 mat_id = fit->is_in_domain() ? 0 : 1; auto add_cell = [&cell_in_grid, &index_point, mat_id] (arr<st, 4> &&indx) { cell_in_grid .push_back (dealii::CellData<2>{ index_point[indx[0]].index, index_point[indx[1]].index, index_point[indx[2]].index, index_point[indx[3]].index, {.material_id = mat_id}}); };
int main() { //construct two non-intersecting nested polygons Polygon_2 polygon1; polygon1.push_back(Point_2(0.0, 0.0)); polygon1.push_back(Point_2(2.0, 0.0)); polygon1.push_back(Point_2(1.7, 1.0)); polygon1.push_back(Point_2(2.0, 2.0)); polygon1.push_back(Point_2(0.0, 2.0)); Polygon_2 polygon2; polygon2.push_back(Point_2(0.5, 0.5)); polygon2.push_back(Point_2(1.5, 0.5)); polygon2.push_back(Point_2(1.5, 1.5)); polygon2.push_back(Point_2(0.5, 1.5)); //Insert the polyons into a constrained triangulation CDT cdt; insert_polygon(cdt, polygon1); insert_polygon(cdt, polygon2); //Extract point and provide the an index std::vector< triangulation_point > points ; for ( CDT::Vertex_iterator it = cdt.vertices_begin(); it != cdt.vertices_end(); ++it ){ it->info() = points.size() ; points.push_back( it->point() ); } //Mark facets that are inside the domain bounded by the polygon mark_domains(cdt); // int count = 0; for (CDT::Finite_faces_iterator fit = cdt.finite_faces_begin(); fit != cdt.finite_faces_end(); ++fit) { if (fit->info().in_domain()){ ++count; } } /* * export */ std::ofstream ofs("polygon_triangulation2.obj"); if ( ! ofs.good() ){ std::cout << "can't open file" << std::endl; return 1 ; } //-- print vertices ofs << "# " << points.size() << " vertices"<< std::endl ; for ( size_t i = 0; i < points.size(); i++ ){ ofs << "v " << points[i] << " 0.0" << std::endl; } //-- print faces ofs << "# " << cdt.number_of_faces() << " faces"<< std::endl ; // warning : Delaunay_triangulation_2::All_faces_iterator iterator over infinite faces for ( CDT::Finite_faces_iterator it = cdt.finite_faces_begin(); it != cdt.finite_faces_end(); ++it ) { //ignore holes if ( ! it->info().in_domain() ){ continue ; } size_t ia = it->vertex(0)->info(); size_t ib = it->vertex(1)->info(); size_t ic = it->vertex(2)->info(); assert( it->is_valid() ); //assert ( ia < cdt.number_of_vertices() || ib < tri.number_of_vertices() || ic < tri.number_of_vertices() ) ; ofs << "f " << ( ia + 1 ) << " " << ( ib + 1 ) << " " << ( ic + 1 ) << std::endl; } return 0; }
void ofxPoly2Tri::doTriangulation(vector<p2t::Point*> bound) { CDT *cdt = new CDT(bound); vector<p2t::Point*> cdtPoints; if (steinerpoints.size()>0) { //ADD POINTS for (int i=0;i<steinerpoints.size();++i) { p2t::Point *point = new p2t::Point(steinerpoints[i].x,steinerpoints[i].y); cdtPoints.push_back(point); cdt->AddPoint(point); } } vector<p2t::Point*> cdtHolePoints; if (holes.size()>0) { //ADD HOLES for (int i=0;i<holes.size();++i) { vector<p2t::Point*> hole; vector<ofPoint>holepoints = holes[i].getVertices(); for (int i=0;i<holepoints.size();++i) { p2t::Point *p = new p2t::Point(); p->set(holepoints[i].x, holepoints[i].y); cdtHolePoints.push_back(p); hole.push_back(p); } cdt->AddHole(hole); } } cdt->Triangulate(); if (bUseVboMesh) { vboMesh.clear(); vboMesh.setUsage(GL_DYNAMIC_DRAW); vboMesh.setMode(OF_PRIMITIVE_TRIANGLES); for (int i = 0; i < cdt->GetTriangles().size(); i++){ p2t::Triangle *ortriangle = cdt->GetTriangles()[i]; if (ortriangle->IsInterior()) { vboMesh.addVertex(ofVec3f(ortriangle->GetPoint(0)->x,ortriangle->GetPoint(0)->y,0)); vboMesh.addVertex(ofVec3f(ortriangle->GetPoint(1)->x,ortriangle->GetPoint(1)->y,0)); vboMesh.addVertex(ofVec3f(ortriangle->GetPoint(2)->x,ortriangle->GetPoint(2)->y,0)); float val =ofRandom(220,255); vboMesh.addColor(ofColor(val,val,val)); vboMesh.addColor(ofColor(val,val,val)); vboMesh.addColor(ofColor(val,val,val)); vboMesh.addNormal(ofVec3f(0,0,1)); vboMesh.addNormal(ofVec3f(0,0,1)); vboMesh.addNormal(ofVec3f(0,0,1)); float xval = ((ortriangle->GetPoint(0)->x+scalex)/(scalex*2))*512; float yval = ((ortriangle->GetPoint(0)->y+scaley)/(scaley*2))*512; float xvala = ((ortriangle->GetPoint(1)->x+scalex)/(scalex*2))*512; float yvala = ((ortriangle->GetPoint(1)->y+scaley)/(scaley*2))*512; float xvalb = ((ortriangle->GetPoint(2)->x+scalex)/(scalex*2))*512; float yvalb = ((ortriangle->GetPoint(2)->y+scaley)/(scaley*2))*512; vboMesh.addTexCoord(ofVec2f(xval,yval)); vboMesh.addTexCoord(ofVec2f(xvala,yvala)); vboMesh.addTexCoord(ofVec2f(xvalb,yvalb)); } } } else { triangulatedMesh.clear(); triangulatedMesh.setMode(OF_PRIMITIVE_TRIANGLES); for (int i = 0; i < cdt->GetTriangles().size(); i++){ p2t::Triangle *ortriangle = cdt->GetTriangles()[i]; if (ortriangle->IsInterior()) { //ofColor randomColor = ofColor(ofRandom(255),ofRandom(255),ofRandom(255)); triangulatedMesh.addVertex(ofVec3f(ortriangle->GetPoint(0)->x,ortriangle->GetPoint(0)->y)); triangulatedMesh.addVertex(ofVec3f(ortriangle->GetPoint(1)->x,ortriangle->GetPoint(1)->y)); triangulatedMesh.addVertex(ofVec3f(ortriangle->GetPoint(2)->x,ortriangle->GetPoint(2)->y)); float val =ofRandom(220,255); triangulatedMesh.addColor(ofColor(val,val,val)); triangulatedMesh.addColor(ofColor(val,val,val)); triangulatedMesh.addColor(ofColor(val,val,val)); triangulatedMesh.addNormal(ofVec3f(0,0,1)); triangulatedMesh.addNormal(ofVec3f(0,0,1)); triangulatedMesh.addNormal(ofVec3f(0,0,1)); float xval = ((ortriangle->GetPoint(0)->x+scalex)/(scalex*2))*512; float yval = ((ortriangle->GetPoint(0)->y+scaley)/(scaley*2))*512; float xvala = ((ortriangle->GetPoint(1)->x+scalex)/(scalex*2))*512; float yvala = ((ortriangle->GetPoint(1)->y+scaley)/(scaley*2))*512; float xvalb = ((ortriangle->GetPoint(2)->x+scalex)/(scalex*2))*512; float yvalb = ((ortriangle->GetPoint(2)->y+scaley)/(scaley*2))*512; triangulatedMesh.addTexCoord(ofVec2f(xval,yval)); triangulatedMesh.addTexCoord(ofVec2f(xvala,yvala)); triangulatedMesh.addTexCoord(ofVec2f(xvalb,yvalb)); } } } //free the memory again for (vector<p2t::Point*>::iterator it = cdtPoints.begin(); it != cdtPoints.end(); ++it) { delete *it; } for (vector<p2t::Point*>::iterator it = cdtHolePoints.begin(); it != cdtHolePoints.end(); ++it) { delete *it; } delete cdt; cdt=NULL; }
bool Delaunay2dMesh::buildMesh( const std::vector<CCVector2>& points2D, const std::vector<int>& segments2D, char* outputErrorStr/*=0*/) { #if defined(USE_CGAL_LIB) //CGAL boilerplate typedef CGAL::Exact_predicates_inexact_constructions_kernel K; //We define a vertex_base with info. The "info" (size_t) allow us to keep track of the original point index. typedef CGAL::Triangulation_vertex_base_with_info_2<size_t, K> Vb; typedef CGAL::Constrained_triangulation_face_base_2<K> Fb; typedef CGAL::No_intersection_tag Itag; //This tag could ben changed if we decide to handle intersection typedef CGAL::Triangulation_data_structure_2<Vb, Fb> Tds; typedef CGAL::Constrained_Delaunay_triangulation_2<K, Tds, Itag> CDT; typedef CDT::Point cgalPoint; std::vector< std::pair<cgalPoint, size_t > > constraints; size_t constrCount = segments2D.size(); try { constraints.reserve(constrCount); } catch (const std::bad_alloc&) { if (outputErrorStr) strcpy(outputErrorStr, "Not enough memory"); return false; }; //We create the Constrained Delaunay Triangulation (CDT) CDT cdt; //We build the constraints for(size_t i = 0; i < constrCount; ++i) { const CCVector2 * pt = &points2D[segments2D[i]]; constraints.push_back(std::make_pair(cgalPoint(pt->x, pt->y), segments2D[i])); } //The CDT is built according to the constraints cdt.insert(constraints.begin(), constraints.end()); m_numberOfTriangles = static_cast<unsigned >(cdt.number_of_faces()); m_triIndexes = new int[cdt.number_of_faces()*3]; //The cgal data structure is converted into CC one if (m_numberOfTriangles > 0) { int faceCount = 0; for (CDT::Face_iterator face = cdt.faces_begin(); face != cdt.faces_end(); ++face, faceCount+=3) { m_triIndexes[0+faceCount] = static_cast<int>(face->vertex(0)->info()); m_triIndexes[1+faceCount] = static_cast<int>(face->vertex(1)->info()); m_triIndexes[2+faceCount] = static_cast<int>(face->vertex(2)->info()); }; } m_globalIterator = m_triIndexes; m_globalIteratorEnd = m_triIndexes + 3*m_numberOfTriangles; return true; #else if (outputErrorStr) strcpy(outputErrorStr, "CGAL library not supported"); return false; #endif }
/* * BuildCutLinesInDEM * * This routine builds horizontal and vertical lines in a DEM via constraints. * Useful for cutting over on a rectangularly mapped texture. * * The DEM points that are used are removed from the mesh to keep them from getting hit multiple times. * */ void BuildCutLinesInDEM( DEMGeo& ioDem, CDT& outMesh, int segments) // Number of cuts per dim, 1 means no action taken! { CDT::Face_handle local; int x_interval = (ioDem.mWidth-1) / segments; int y_interval = (ioDem.mHeight-1) / segments; vector<CDT::Vertex_handle> junctions; junctions.resize((segments+1)*(segments+1)); // First, there will be some crossing points - add every one of them to the triangulation. int x, y, dx, dy; for (y = 0; y < ioDem.mHeight; y += y_interval) for (x = 0; x < ioDem.mWidth; x += x_interval) { float h = ioDem(x,y); if (h != NO_DATA) { // gMeshPoints.push_back(Point_2(ioDem.x_to_lon(x),ioDem.y_to_lat(y))); #if !NO_TRIANGULATE CDT::Vertex_handle vv = outMesh.insert(CDT::Point(ioDem.x_to_lon(x),ioDem.y_to_lat(y)), local); vv->info().height = h; local = vv->face(); #endif junctions[(x / x_interval) + (y / y_interval) * (segments+1)] = vv; } else AssertPrintf("Needed DEM point AWOL - %d,%d.\n",x,y); } // Next, add the vertical segments. Run through each vertical stripe except the edges, // for every horizontal one except the top. This is each vertical band we must add. for (y = y_interval; y < ioDem.mHeight; y += y_interval) for (x = x_interval; x < (ioDem.mWidth-x_interval); x += x_interval) { CDT::Vertex_handle v1, v2; v1 = junctions[(x / x_interval) + ((y-y_interval) / y_interval) * (segments+1)]; for (dy = y - y_interval + 1; dy < y; ++dy) { float h = ioDem(x,dy); if (h != NO_DATA) { // gMeshPoints.push_back(Point_2(ioDem.x_to_lon(x),ioDem.y_to_lat(dy))); #if !NO_TRIANGULATE v2 = outMesh.insert(CDT::Point(ioDem.x_to_lon(x),ioDem.y_to_lat(dy)), local); v2->info().height = h; local = v2->face(); outMesh.insert_constraint(v1, v2); v2 = v1; #endif } } v2 = junctions[(x / x_interval) + (y / y_interval) * (segments+1)]; outMesh.insert_constraint(v1, v2); } // Same thing but horizontal-like. for (y = y_interval; y < (ioDem.mHeight-y_interval); y += y_interval) for (x = x_interval; x < ioDem.mWidth; x += x_interval) { CDT::Vertex_handle v1, v2; v1 = junctions[((x-x_interval) / x_interval) + (y / y_interval) * (segments+1)]; for (dx = x - x_interval + 1; dx < x; ++dx) { float h = ioDem(dx,y); if (h != NO_DATA) { // gMeshPoints.push_back(Point_2(ioDem.x_to_lon(dx),ioDem.y_to_lat(y))); #if !NO_TRIANGULATE v2 = outMesh.insert(CDT::Point(ioDem.x_to_lon(dx),ioDem.y_to_lat(y)), local); v2->info().height = h; local = v2->face(); outMesh.insert_constraint(v1, v2); v2 = v1; #endif } } v2 = junctions[(x / x_interval) + (y / y_interval) * (segments+1)]; outMesh.insert_constraint(v1, v2); } }