// This customized version carves holes defined by the regions.
    // It'll remove any element which doesn't receive any region.
    int custom_carveholes(struct mesh *m, struct behavior *b, const int *outside, const int *inside)
    {
        struct otri neighbortri;
        struct otri triangleloop;
        struct osub subsegloop;
        triangle **temptri;
        triangle ptr;                     /* Temporary variable used by sym(). */
        double area;
        double attribute;
        double triangle_attribute;
        int sane_mesh;

        poolinit(& m->viri, sizeof( triangle * ), VIRUSPERBLOCK, VIRUSPERBLOCK, 0);

        /* Assigns every triangle a regional attribute of -1 */
        traversalinit(& m->triangles);
        triangleloop.orient = 0;
        triangleloop.tri = triangletraverse(m);
        while ( triangleloop.tri != ( triangle * ) NULL ) {
            setelemattribute(triangleloop, m->eextras, -1.0);
            triangleloop.tri = triangletraverse(m);
        }

        sane_mesh = 1;

        /* Loop over all segments */
        traversalinit(& m->subsegs);
        subsegloop.ss = subsegtraverse(m);
        subsegloop.ssorient = 0;
        while ( subsegloop.ss != ( subseg * ) NULL ) {
            if ( subsegloop.ss != m->dummysub ) {
                /* First neighbor. */
                ssymself(subsegloop);
                stpivot(subsegloop, neighbortri);
                if ( neighbortri.tri != m->dummytri ) {
                    area = 0.0; /// @todo Possible set this as the minimum as well.
                    attribute = outside [ mark(subsegloop) - 1 ];
                    triangle_attribute = elemattribute(neighbortri, m->eextras);

                    /* The region no number yet. */
                    if ( triangle_attribute < 0 && attribute >= 0 ) {
                        infect(neighbortri);
                        temptri = ( triangle ** ) poolalloc(& m->viri);
                        * temptri = neighbortri.tri;
                        /* Apply one region's attribute and/or area constraint. */
                        regionplague(m, b, attribute, area);
                        /* The virus pool should be empty now. */
                    } else if ( attribute >= 0 && triangle_attribute >= 0 && attribute != triangle_attribute ) {
                        /* Check for problems. */
                        vertex v1, v2, v3;
                        org(neighbortri, v1);
                        dest(neighbortri, v2);
                        apex(neighbortri, v3);
                        fprintf(stdout, "Error: inconsistent region information (new %d, old %d from %d) (outside) at (%e, %e)\n",
                                ( int ) attribute, ( int ) triangle_attribute, ( int ) mark(subsegloop), ( v1 [ 0 ] + v2 [ 0 ] + v3 [ 0 ] ) / 3, ( v1 [ 1 ] + v2 [ 1 ] + v3 [ 1 ] ) / 3);
                        sane_mesh = 0;
                    }
                }

                /* Second neighbor (same procedure). */
                ssymself(subsegloop);
                stpivot(subsegloop, neighbortri);
                if ( neighbortri.tri != m->dummytri ) {
                    area = 0.0;
                    attribute = inside [ mark(subsegloop) - 1 ];
                    triangle_attribute = elemattribute(neighbortri, m->eextras);

                    if ( triangle_attribute < 0 && attribute >= 0 ) {
                        infect(neighbortri);
                        temptri = ( triangle ** ) poolalloc(& m->viri);
                        * temptri = neighbortri.tri;
                        regionplague(m, b, attribute, area);
                    } else if ( attribute >= 0 && triangle_attribute >= 0 && attribute != triangle_attribute ) {
                        vertex v1, v2, v3;
                        org(neighbortri, v1);
                        dest(neighbortri, v2);
                        apex(neighbortri, v3);
                        fprintf(stdout, "Error: inconsistent region information (new %d, old %d from %d) (inside) at (%e, %e)\n",
                                ( int ) attribute, ( int ) triangle_attribute, ( int ) mark(subsegloop), ( v1 [ 0 ] + v2 [ 0 ] + v3 [ 0 ] ) / 3, ( v1 [ 1 ] + v2 [ 1 ] + v3 [ 1 ] ) / 3);
                        sane_mesh = 0;
                    }
                }

                subsegloop.ss = subsegtraverse(m);
            }
        }

        /* Remove all triangles with marker 0.0 */
        traversalinit(& m->triangles);
        triangleloop.tri = triangletraverse(m);
        int triangle_number = 0;
        while ( triangleloop.tri != ( triangle * ) NULL ) {
            if ( triangleloop.tri != m->dummytri ) {
                triangle_number++;
                attribute = elemattribute(triangleloop, m->eextras);
                if ( attribute == -1.0 ) {
                    fprintf(stderr, "Broken mesh at triangle %d\n", triangle_number);
                    sane_mesh = 0;
                } else if ( attribute == 0.0 ) {
                    infect(triangleloop);
                    temptri = ( triangle ** ) poolalloc(& m->viri);
                    * temptri = triangleloop.tri;
                }
            }
            triangleloop.tri = triangletraverse(m);
        }
        /* Remove the marked elements */
        plague(m, b);

        if ( b->regionattrib && !b->refine ) {
            /* Note the fact that each triangle has an additional attribute. */
            m->eextras++;
        }

        /* Free up memory. */
        pooldeinit(& m->viri);

        return sane_mesh;
    }
Exemple #2
0
TriangleIterator::TriangleIterator(const TIN * theTIN) : mTIN( const_cast<TIN *>(theTIN) )
{
	traversalinit( &(theTIN->mMesh->triangles) );
	mCurrentTriangle.tri = triangletraverse( theTIN->mMesh );
	mCurrentTriangle.orient = 0;
}
Exemple #3
0
TriangleIterator& TriangleIterator::operator++()
{
	mCurrentTriangle.tri = triangletraverse( mTIN->mMesh );
	return *this;
}
Exemple #4
0
void TIN::create(const mydefs::Points3d& thePoints3d)
{
	// Set input values for triangulation
	TTriangulationIO in;
	// Number of points
	in.numberofpoints = thePoints3d.size(); 
	// One attribute for Z coordinate
	in.numberofpointattributes = 1; 
	// Allocate memory for array of X and Y coordinates
	in.pointlist = (double *) malloc(in.numberofpoints * 2 * sizeof(double));
	// Allocate memory for array of Z coordinates
	in.pointattributelist = (double *) malloc(in.numberofpoints *
                                          in.numberofpointattributes *
                                          sizeof(double));
	in.pointmarkerlist = (int *) malloc(in.numberofpoints * sizeof(int));
	// Zero segments, holes and regions
	in.numberofsegments = 0;
	in.numberofholes = 0;
	in.numberofregions = 0;

	// Populate arrays of coordinates
	int i = 0;
	for(mydefs::Points3d::const_iterator iter = thePoints3d.begin(); 
		iter != thePoints3d.end(); 
		++iter)
	{
		in.pointlist[2*i] = (*iter)[0];
		in.pointlist[2*i+1] = (*iter)[1];
		in.pointattributelist[i] = (*iter)[2];
		
		if(mMinZ > (*iter)[2])
		{
			mMinZ = (*iter)[2];
		}
		if(mMaxZ < (*iter)[2])
		{
			mMaxZ = (*iter)[2];
		}

		++i;
	}
	
	// Prepare for triangulation
	transfernodes(mMesh, mBehavior, in.pointlist, in.pointattributelist,
			in.pointmarkerlist, in.numberofpoints,
			in.numberofpointattributes);

	// Triangulate points
	mMesh->hullsize = delaunay(mMesh, mBehavior);

	// Necessary maintenance 
	mMesh->infvertex1 = (TVertex) NULL;
	mMesh->infvertex2 = (TVertex) NULL;
	mMesh->infvertex3 = (TVertex) NULL;
	mMesh->edges = (3l * mMesh->triangles.items + mMesh->hullsize) / 2l;

	// Set most recent triangle
	traversalinit(&mMesh->triangles);
	mRecentTri->tri = triangletraverse(mMesh);
	mRecentTri->orient = 0;

	// Free memory
	free(in.pointmarkerlist);
	free(in.pointattributelist);
	free(in.pointlist);
}