Beispiel #1
0
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;
}
Beispiel #2
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);
	}
}
Beispiel #5
0
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;
}
Beispiel #6
0
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()));
}
Beispiel #13
0
 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);
   }
  
 }
Beispiel #14
0
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
}
Beispiel #15
0
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;
    }
  }
}
Beispiel #16
0
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;
    }
  }
}
Beispiel #17
0
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}});
        };
Beispiel #18
0
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;
}
Beispiel #20
0
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
}
Beispiel #21
0
/*
 * 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);
	}
}