Esempio n. 1
0
static void DrawPolyPolygonRaw(Draw& draw, const Point *vertices, int vertex_count,
	const int *subpolygon_counts, int subpolygon_count_count,
	bool is_inside, int outline_width, Color outline_color
)
{
#ifdef SYSTEMDRAW
	SystemDraw *w = dynamic_cast<SystemDraw *>(&draw);
	if(w) { SystemDraw& draw = *w;
#endif
	draw.SetDrawPen(outline_width, outline_color);
	ASSERT(sizeof(POINT) == sizeof(Point)); // modify algorithm when not
	enum { MAX_POLY = 8000 };
	if(subpolygon_count_count == 1 && vertex_count < MAX_POLY)
		Polygon(draw, (const POINT *)vertices, vertex_count);
	else if(vertex_count < MAX_POLY)
		PolyPolygon(draw, (const POINT *)vertices, subpolygon_counts, subpolygon_count_count);
	else {
		if(is_inside) {
			draw.SetDrawPen(PEN_NULL, Black);
			Vector<Point> split_vertices;
			Vector<int> split_counts;
		#ifdef SYSTEMDRAW
			SplitPolygon(vertices, vertex_count, subpolygon_counts, subpolygon_count_count,
				split_vertices, split_counts, Size(9999, 9999));
		#else
			SplitPolygon(vertices, vertex_count, subpolygon_counts, subpolygon_count_count,
				split_vertices, split_counts, draw.GetClip());
		#endif
			//!! todo: maxcount for splitpolygon
			const Point *sv = split_vertices.Begin();
			for(const int *sc = split_counts.Begin(), *se = split_counts.End(); sc < se; sc++) {
				Polygon(draw, (const POINT *)sv, *sc);
				sv += *sc;
			}
		}
		if(outline_width != PEN_NULL) {
			draw.DrawPolyPolyline(vertices, vertex_count, subpolygon_counts, subpolygon_count_count,
				outline_width, outline_color, Null);
			Buffer<Point> finish(2 * subpolygon_count_count);
			Buffer<int> counts(subpolygon_count_count);
			Fill(&counts[0], &counts[subpolygon_count_count], 2);
			Point *d = finish;
			const Point *p = vertices;
			const int *c = subpolygon_counts, *e = c + subpolygon_count_count;
			while(c < e)
			{
				*d++ = *p;
				*d++ = (p += *c++)[-1];
			}
			draw.DrawPolyPolyline(finish, 2 * subpolygon_count_count,
				counts, subpolygon_count_count, outline_width, outline_color, Null);
		}
		draw.SetDrawPen(outline_width, outline_color);
	}
#ifdef SYSTEMDRAW
	}
#endif
}
Esempio n. 2
0
static void FillPolyPolygonRaw(GC gc, Drawable drawable, Rect clip, Point offset,
	const Point *vertices, int vertex_count,
	const int *subpolygon_counts, int subpolygon_count_count)
{
	enum { MAX_VERTEX_COUNT = 10000 };

	if(subpolygon_count_count == 1 && vertex_count <= MAX_VERTEX_COUNT) {
		Buffer<XPoint> out_points(vertex_count);
		const Point *in = vertices;
		for(XPoint *out = out_points, *end = out + vertex_count; out < end; out++, in++)
		{
			out -> x = (short)(in -> x + offset.x);
			out -> y = (short)(in -> y + offset.y);
		}
		XFillPolygon(Xdisplay, drawable, gc,
			out_points, vertex_count, Nonconvex, CoordModeOrigin);
	}
	else {
		Vector<Point> split_vertices;
		ASSERT(sizeof(XPoint) <= sizeof(Point)); // modify algorithm when not
		Vector<int> split_counts;
		SplitPolygon(vertices, vertex_count, subpolygon_counts, subpolygon_count_count,
			split_vertices, split_counts, clip);
		const Point *sv = split_vertices.Begin();
		XPoint *dv = reinterpret_cast<XPoint *>(split_vertices.Begin());
		for(const int *sc = split_counts.Begin(), *se = split_counts.End(); sc < se; sc++) {
			for(XPoint *db = dv, *de = dv + *sc; db < de; db++, sv++) {
				db -> x = (short)(sv -> x + offset.x);
				db -> y = (short)(sv -> y + offset.y);
			}
			XFillPolygon(Xdisplay, drawable, gc, dv, *sc, Nonconvex, CoordModeOrigin);
		}
	}
}
Esempio n. 3
0
void DropPolygonRecursive( node_t *n, polygon_t *p )
{
	if ( n->child[0] == -1 && n->child[1] == -1 )
	{
		fp_t	area;
		// leaf
		
		area = PolygonArea( p );
//		printf( " split: %f\n", area );
		if ( area > g_best_area )
		{
			g_best_area = area;
			g_best_leaf = n;
		}
	}
	else
	{
		polygon_t	*front;
		polygon_t	*back;
		// node
	       
		SplitPolygon( p, n->norm, n->dist, &front, &back );

		if ( front )
		{
			DropPolygonRecursive( &g_nodes[n->child[0]], front );	
			FreePolygon( front );
		}
		if ( back )
		{
			DropPolygonRecursive( &g_nodes[n->child[1]], back );
			FreePolygon( back );
		}
	}
}
Esempio n. 4
0
void ClipPolygonInPlace( polygon_t **inout, vec3d_t norm, fp_t dist )
{
	polygon_t	*front, *back;

	SplitPolygon( *inout, norm, dist, &front, &back );
	
	if ( front )
		FreePolygon( front );

	FreePolygon( *inout );

	*inout = back;
}
Esempio n. 5
0
void SplitPortal ( PORTAL* Portal, PLANE* Plane, PORTAL* FrontSplit, PORTAL* BackSplit )
{
	// this function simply calls SplitPolygon, and is a convenient wrapper
	// for the splitting of the POLYGON safe type castable portal type

	SplitPolygon ( ( POLYGON* ) Portal, Plane, ( POLYGON* ) FrontSplit, ( POLYGON* ) BackSplit );

	FrontSplit->NumberOfLeafs = Portal->NumberOfLeafs;
	BackSplit->NumberOfLeafs  = Portal->NumberOfLeafs;

	memcpy ( FrontSplit->LeafOwnerArray, Portal->LeafOwnerArray, sizeof ( long ) * Portal->NumberOfLeafs );
	memcpy ( BackSplit->LeafOwnerArray,  Portal->LeafOwnerArray, sizeof ( long ) * Portal->NumberOfLeafs );
}
Esempio n. 6
0
void
BSPTree::BuildTree(UniquePtr<BSPTreeNode>& aRoot,
                   std::deque<gfx::Polygon3D>& aPolygons)
{
  if (aPolygons.empty()) {
    return;
  }

  const gfx::Polygon3D& splittingPlane = aRoot->First();
  std::deque<gfx::Polygon3D> backPolygons, frontPolygons;

  for (gfx::Polygon3D& polygon : aPolygons) {
    size_t pos = 0, neg = 0;
    nsTArray<float> dots = CalculateDotProduct(splittingPlane, polygon,
                                               pos, neg);

    // Back polygon
    if (pos == 0 && neg > 0) {
      backPolygons.push_back(std::move(polygon));
    }
    // Front polygon
    else if (pos > 0 && neg == 0) {
     frontPolygons.push_back(std::move(polygon));
    }
    // Coplanar polygon
    else if (pos == 0 && neg == 0) {
      aRoot->polygons.push_back(std::move(polygon));
    }
    // Polygon intersects with the splitting plane.
    else if (pos > 0 && neg > 0) {
      nsTArray<gfx::Point3D> backPoints, frontPoints;
      SplitPolygon(splittingPlane, polygon, dots, backPoints, frontPoints);

      backPolygons.push_back(gfx::Polygon3D(std::move(backPoints)));
      frontPolygons.push_back(gfx::Polygon3D(std::move(frontPoints)));
    }
  }

  if (!backPolygons.empty()) {
    aRoot->back.reset(new BSPTreeNode(PopFront(backPolygons)));
    BuildTree(aRoot->back, backPolygons);
  }

  if (!frontPolygons.empty()) {
    aRoot->front.reset(new BSPTreeNode(PopFront(frontPolygons)));
    BuildTree(aRoot->front, frontPolygons);
  }
}
Esempio n. 7
0
// Please only call this on triangulated meshes.. that makes the rest of my coding easier
void SplitIntersecting(std::vector<pcs_polygon> &polygons, vector3d plane_point, vector3d plane_normal)
{
	std::vector<pcs_polygon> newpolys;
	unsigned int i;
	for (i = 0; i < polygons.size(); i++)
	{
		if (Intersects(polygons[i], plane_point, plane_normal))
		{
			SplitPolygon(polygons, i, plane_point, plane_normal, newpolys);
		}
	}
	// add new polygons

	int in = polygons.size();
	polygons.resize(in+newpolys.size());
	for (i = 1; i < newpolys.size(); i++)
	{
		polygons[in+i] = newpolys[i];
	}
}
Esempio n. 8
0
/*
  ====================
  Portal_SplitNode

  ====================
*/
void Portal_SplitNode( cnode_t *node )
{
	cplane_t		*pl;
	portal_t		*p, *pnext;
	int		side;
	cnode_t		*othernode;
	portal_t	*frontportal, *backportal;
	polygon_t	*front, *back;

	pl = node->pl;

	side = 0;
	for ( p = node->portals; p ; p=pnext )
	{
		if ( p->nodes[0] == node )
			side = 0;
		else if ( p->nodes[1] == node )
			side = 1;
		else
			Error( "Portal_SplitNode: can't find node in portal.\n" );

		pnext = p->next[side];

		othernode = p->nodes[!side];

		RemovePortalFromNode( p, p->nodes[0] );
		RemovePortalFromNode( p, p->nodes[1] );

		SplitPolygon( p->p, pl->norm, pl->dist, &front, &back );
		FreePolygon( p->p );


		if ( !front && !back )
			Error( "Portal_SplitNode: no front and back after split.\n" );

		if ( !front )
		{
			// polygon is back
			p->p = back;

			if ( side ) // node was back of portal
				AddPortalToNodes( p, othernode, node->child[1] );
			else // node was front
				AddPortalToNodes( p, node->child[1], othernode );
			continue;
		}

		if ( !back )
		{
			// polygon is front
			p->p = front;

			if ( side ) // node was back of portal
				AddPortalToNodes( p, othernode, node->child[0] );
			else
				AddPortalToNodes( p, node->child[0], othernode );
			continue;
		}

		//
		// portal got split
		//
		frontportal = p;
		frontportal->p = front;

		backportal = NewPortal();
		memcpy( backportal, p, sizeof( portal_t ) );
		backportal->p = back;

		if ( side ) // node was back of portal
		{
			AddPortalToNodes( frontportal, othernode, node->child[0] );
			AddPortalToNodes( backportal, othernode, node->child[1] );
		}
		else
		{
			AddPortalToNodes( frontportal, node->child[0], othernode );
			AddPortalToNodes( backportal, node->child[1], othernode );
		}
	}

	node->portals = NULL;
}
    MagicDGP::LightMesh3D* PoissonReconstruction::SurfaceTrimmer(int argc , char* argv[], std::vector< PlyValueVertex< float > >& vertices, std::vector< std::vector< int > >& polygons)
    {
        cmdLineString In( "in" ) , Out( "out" );
        cmdLineInt Smooth( "smooth" , 5 );
        cmdLineFloat Trim( "trim" ) , IslandAreaRatio( "aRatio" , 0.001f );
        cmdLineFloatArray< 2 > ColorRange( "color" );
        cmdLineReadable PolygonMesh( "polygonMesh" );

        cmdLineReadable* params[] =
        {
            &In , &Out , &Trim , &PolygonMesh , &ColorRange , &Smooth , &IslandAreaRatio
        };

        int paramNum = sizeof(params)/sizeof(cmdLineReadable*);
        cmdLineParse( argc , argv, paramNum , params , 0 );

        float min , max;
        //std::vector< PlyValueVertex< float > > vertices;
        //std::vector< std::vector< int > > polygons;

        //int ft , commentNum = paramNum+2;
        //char** comments;
        //bool readFlags[ PlyValueVertex< float >::Components ];
        //PlyReadPolygons( In.value , vertices , polygons , PlyValueVertex< float >::Properties , PlyValueVertex< float >::Components , ft , &comments , &commentNum , readFlags );
        //if( !readFlags[3] ){ fprintf( stderr , "[ERROR] vertices do not have value flag\n" ) ; return EXIT_FAILURE; }

        for( int i=0 ; i<Smooth.value ; i++ ) SmoothValues( vertices , polygons );

        min = max = vertices[0].value;
        for( size_t i=0 ; i<vertices.size() ; i++ ) min = std::min< float >( min , vertices[i].value ) , max = std::max< float >( max , vertices[i].value );
        printf( "Value Range: [%f,%f]\n" , min , max );


        if( Trim.set )
        {
            hash_map< long long , int > vertexTable;
            std::vector< std::vector< int > > ltPolygons , gtPolygons;
            std::vector< bool > ltFlags , gtFlags;

            /*for( int i=0 ; i<paramNum+2 ; i++ ) comments[i+commentNum]=new char[1024];
            sprintf( comments[commentNum++] , "Running Surface Trimmer (V5)" );
            if(              In.set ) sprintf(comments[commentNum++],"\t--%s %s" , In.name , In.value );
            if(             Out.set ) sprintf(comments[commentNum++],"\t--%s %s" , Out.name , Out.value );
            if(            Trim.set ) sprintf(comments[commentNum++],"\t--%s %f" , Trim.name , Trim.value );
            if(          Smooth.set ) sprintf(comments[commentNum++],"\t--%s %d" , Smooth.name , Smooth.value );
            if( IslandAreaRatio.set ) sprintf(comments[commentNum++],"\t--%s %f" , IslandAreaRatio.name , IslandAreaRatio.value );
            if(     PolygonMesh.set ) sprintf(comments[commentNum++],"\t--%s" , PolygonMesh.name );*/

            double t=Time();
            for( size_t i=0 ; i<polygons.size() ; i++ ) SplitPolygon( polygons[i] , vertices , &ltPolygons , &gtPolygons , &ltFlags , &gtFlags , vertexTable , Trim.value );
            if( IslandAreaRatio.value>0 )
            {
                std::vector< std::vector< int > > _ltPolygons , _gtPolygons;
                std::vector< std::vector< int > > ltComponents , gtComponents;
                SetConnectedComponents( ltPolygons , ltComponents );
                SetConnectedComponents( gtPolygons , gtComponents );
                std::vector< double > ltAreas( ltComponents.size() , 0. ) , gtAreas( gtComponents.size() , 0. );
                std::vector< bool > ltComponentFlags( ltComponents.size() , false ) , gtComponentFlags( gtComponents.size() , false );
                double area = 0.;
                for( size_t i=0 ; i<ltComponents.size() ; i++ )
                {
                    for( size_t j=0 ; j<ltComponents[i].size() ; j++ )
                    {
                        ltAreas[i] += PolygonArea( vertices , ltPolygons[ ltComponents[i][j] ] );
                        ltComponentFlags[i] = ( ltComponentFlags[i] || ltFlags[ ltComponents[i][j] ] );
                    }
                    area += ltAreas[i];
                }
                for( size_t i=0 ; i<gtComponents.size() ; i++ )
                {
                    for( size_t j=0 ; j<gtComponents[i].size() ; j++ )
                    {
                        gtAreas[i] += PolygonArea( vertices , gtPolygons[ gtComponents[i][j] ] );
                        gtComponentFlags[i] = ( gtComponentFlags[i] || gtFlags[ gtComponents[i][j] ] );
                    }
                    area += gtAreas[i];
                }
                for( size_t i=0 ; i<ltComponents.size() ; i++ )
                {
                    if( ltAreas[i]<area*IslandAreaRatio.value && ltComponentFlags[i] ) for( size_t j=0 ; j<ltComponents[i].size() ; j++ ) _gtPolygons.push_back( ltPolygons[ ltComponents[i][j] ] );
                    else                                                               for( size_t j=0 ; j<ltComponents[i].size() ; j++ ) _ltPolygons.push_back( ltPolygons[ ltComponents[i][j] ] );
                }
                for( size_t i=0 ; i<gtComponents.size() ; i++ )
                {
                    if( gtAreas[i]<area*IslandAreaRatio.value && gtComponentFlags[i] ) for( size_t j=0 ; j<gtComponents[i].size() ; j++ ) _ltPolygons.push_back( gtPolygons[ gtComponents[i][j] ] );
                    else                                                               for( size_t j=0 ; j<gtComponents[i].size() ; j++ ) _gtPolygons.push_back( gtPolygons[ gtComponents[i][j] ] );
                }
                ltPolygons = _ltPolygons , gtPolygons = _gtPolygons;
            }
            if( !PolygonMesh.set )
            {
                {
                    std::vector< std::vector< int > > polys = ltPolygons;
                    Triangulate( vertices , ltPolygons , polys ) , ltPolygons = polys;
                }
                {
                    std::vector< std::vector< int > > polys = gtPolygons;
                    Triangulate( vertices , gtPolygons , polys ) , gtPolygons = polys;
                }
            }

            RemoveHangingVertices( vertices , gtPolygons );

            MagicDGP::LightMesh3D* pExportMesh = new MagicDGP::LightMesh3D;
            for (int pIndex = 0; pIndex < vertices.size(); pIndex++)
            {
                PlyValueVertex< float > vert = vertices.at(pIndex);
                MagicMath::Vector3 vertPos(vert.point[0], vert.point[1], vert.point[2]);
                pExportMesh->InsertVertex(vertPos);
            }
            for (int pIndex = 0; pIndex < gtPolygons.size(); pIndex++)
            {
                MagicDGP::FaceIndex faceIdx;
                for (int k = 0; k < 3; k++)
                {
                    faceIdx.mIndex[k] = gtPolygons.at(pIndex).at(k);
                }
                pExportMesh->InsertFace(faceIdx);
            }
            pExportMesh->UpdateNormal();
            
            return pExportMesh;
        }
        else
        {
            //if( ColorRange.set ) min = ColorRange.values[0] , max = ColorRange.values[1];
            //std::vector< PlyColorVertex< float > > outVertices;
            //ColorVertices( vertices , outVertices , min , max );
            ////if( Out.set ) PlyWritePolygons( Out.value , outVertices , polygons , PlyColorVertex< float >::Properties , PlyColorVertex< float >::Components , ft , comments , commentNum );
            //if( Out.set ) PlyWritePolygons( Out.value , outVertices , polygons , PlyColorVertex< float >::Properties , PlyColorVertex< float >::Components , 1 , NULL , 0 );
        }

        return NULL;
    }
Esempio n. 10
0
u_list_t * ScanPolygon( polygon_t *poly, vec3d_t norm, fp_t dist, fp_t step )
{
	fp_t		max_d;
	int		i;
	fp_t		d;
	polygon_t	*remain;

	u_list_t	*frag_list;

//	printf( "dist: %f, step: %f\n", dist,step );
//	Vec3dPrint( norm );

	// get max dist of poly towards the plane
	
	max_d = -999999.9;
	for ( i = 0; i < poly->pointnum; i++ )
	{
		d = Vec3dDotProduct( norm, poly->p[i] ) - dist;
		if ( d > max_d )
			max_d = d;
	}

	if ( max_d < 0.0 )
	{
		d = -ceil( (-max_d)/step ) * step;
	}
	else
	{
		d = ceil( (max_d)/step ) * step;
	}

	dist += d;
	
	remain = CopyPolygon( poly );

	frag_list = NEWTYPE( u_list_t );
	U_InitList( frag_list );

	for( ; remain ; )
	{
		polygon_t	*front, *back;
		
//		printf( "split dist: %f\n", dist );

		SplitPolygon( remain, norm, dist, &front, &back );
		
		if ( front )
		{
			scan_frag_t	*frag;

			frag = NEWTYPE( scan_frag_t );
			frag->p = front;
			frag->dist = dist;
			U_ListInsertAtHead( frag_list, frag );
			
//			printf( "hit!\n" );
			
		}
		
		dist -= step;
		remain = back;
	}
	return frag_list;
}
Esempio n. 11
0
void CSG_SplitBrush_new( cbspbrush_t *in, cplane_t *plane, cbspbrush_t **front, cbspbrush_t **back )
{
	int		i;
	int		exact;
	polygon_t	*splitpoly;
	cbspbrush_t	*b, *f;

	*front = *back = NULL;

	//
	// split plane part of brush ?
	//

	exact = CSG_IsExactOnPlane( in, plane );

	if ( exact == BRUSH_BACK_ON )
	{
		*back = CopyBrush( in );
		return;
	}
	if ( exact == BRUSH_FRONT_ON )
	{
		*front = CopyBrush( in );
		return;
	}

	//
	// real check
	//

	splitpoly = BasePolygonForPlane( plane->norm, plane->dist );

	for ( i = 0; i < in->surfacenum; i++ )
	{
		ClipPolygonInPlace( &splitpoly, in->surfaces[i].pl->norm, in->surfaces[i].pl->dist );
		if ( !splitpoly )
			break;
	}

	if ( !splitpoly )
	{
		// no splitpoly => brush is not split by plane
		// determine on which side of plane is the complete brush

		int	check = -1;

		for ( i = 0; i < in->surfacenum; i++ )
		{
			if ( !in->surfaces[i].p )
				continue;
			check = CheckPolygonWithPlane( in->surfaces[i].p, plane->norm, plane->dist );
			if ( check == POLY_BACK )
				break;
			else if ( check == POLY_FRONT )
				break;
			else if ( check == POLY_ON )
				continue;
			printf( "?" );
		}
		
		if ( check == POLY_BACK )
		{
			*back = CopyBrush( in );
			return;
		}
		else if ( check == POLY_FRONT )
		{
			*front = CopyBrush( in );
			return;
		}
		else
		{
			printf( "can't get planeside of brush.\n" );
			*front = NULL;
			*back = NULL;
			return;
		}
	}

	//
	// split input brush
	//
	
	f = NewBrush( in->surfacenum + 2 );
	b = NewBrush( in->surfacenum + 2 );
	f->surfacenum = b->surfacenum = 0;

	f->original = in->original;
	b->original = in->original;
	f->contents = in->contents;
	b->contents = in->contents;

	for( i = 0; i < in->surfacenum; i++ )
	{
		polygon_t	*fpoly, *bpoly;

		SplitPolygon( in->surfaces[i].p, plane->norm, plane->dist, &fpoly, &bpoly );

		if ( fpoly )
		{
			// add polygon to front brush and copy the rest
			if ( f->surfacenum == in->surfacenum + 2 )
				Error( "reached max surfs\n" );
			memcpy( &f->surfaces[f->surfacenum], &in->surfaces[i], sizeof( csurface_t ) );
			f->surfaces[f->surfacenum].p = fpoly;
			f->surfacenum++;
		}
		if ( bpoly )
		{
			// add polygon to back brush and copy the rest
			if ( b->surfacenum == in->surfacenum + 2 )
				Error( "reached max surfs\n" );
			memcpy( &b->surfaces[b->surfacenum], &in->surfaces[i], sizeof( csurface_t ) );
			b->surfaces[b->surfacenum].p = bpoly;
			b->surfacenum++;
		}
	}

	//
	// add split plane to front and back brush
	//

	// the backside brush gets the plane
	if ( f->surfacenum == in->surfacenum + 2 )
		Error( "reached max surfs\n" );
	b->surfaces[b->surfacenum].pl = plane;
	b->surfaces[b->surfacenum].td = NULL;
	b->surfaces[b->surfacenum].state = SURFACE_STATE_BYSPLIT;
	b->surfaces[b->surfacenum].contents = 0;
	b->surfaces[b->surfacenum].p = splitpoly;
	b->surfacenum++;

	// the frontside brush gets the flipplane
	if ( b->surfacenum == in->surfacenum + 2 )
		Error( "reached max surfs\n" );
	f->surfaces[f->surfacenum].pl = plane->flipplane;
	f->surfaces[f->surfacenum].td = NULL;
	f->surfaces[f->surfacenum].state = SURFACE_STATE_BYSPLIT;
	f->surfaces[f->surfacenum].contents = 0;
	f->surfaces[f->surfacenum].p = PolygonFlip( splitpoly );
	f->surfacenum++;
	
	if ( b->surfacenum < 4 )
	{
		printf( "no back %d\n", b->surfacenum );
		FreeBrush( b );
		b = NULL;
	}
	if ( f->surfacenum < 4 )
	{
		printf( "no front %d\n", f->surfacenum );
		FreeBrush( f );
		f = NULL;
	}

	if ( b )
		CalcBrushBounds( b );
	if ( f )
		CalcBrushBounds( f );

	*back = b;
	*front = f;
}
Esempio n. 12
0
int main( int argc , char* argv[] )
{
	int paramNum = sizeof(params)/sizeof(cmdLineReadable*);
	cmdLineParse( argc-1 , &argv[1] , paramNum , params , 0 );

#if FOR_RELEASE
	if( !In.set || !Trim.set )
	{
		ShowUsage( argv[0] );
		return EXIT_FAILURE;
	}
#else // !FOR_RELEASE
	if( !In.set )
	{
		ShowUsage( argv[0] );
		return EXIT_FAILURE;
	}
#endif // FOR_RELEASE
	float min , max;
	std::vector< PlyValueVertex< float > > vertices;
	std::vector< std::vector< int > > polygons;

	int ft , commentNum = paramNum+2;
	char** comments;
	bool readFlags[ PlyValueVertex< float >::Components ];
	PlyReadPolygons( In.value , vertices , polygons , PlyValueVertex< float >::Properties , PlyValueVertex< float >::Components , ft , &comments , &commentNum , readFlags );
	if( !readFlags[3] ){ fprintf( stderr , "[ERROR] vertices do not have value flag\n" ) ; return EXIT_FAILURE; }
#if 0
	if( Trim.set ) for( int i=0 ; i<Smooth.value ; i++ ) SmoothValues( vertices , polygons , Trim.value-0.5f , Trim.value+0.5f );
	else           for( int i=0 ; i<Smooth.value ; i++ ) SmoothValues( vertices , polygons );
#else
	for( int i=0 ; i<Smooth.value ; i++ ) SmoothValues( vertices , polygons );
#endif 
	min = max = vertices[0].value;
	for( size_t i=0 ; i<vertices.size() ; i++ ) min = std::min< float >( min , vertices[i].value ) , max = std::max< float >( max , vertices[i].value );
	printf( "Value Range: [%f,%f]\n" , min , max );


	if( Trim.set )
	{
		hash_map< long long , int > vertexTable;
		std::vector< std::vector< int > > ltPolygons , gtPolygons;
		std::vector< bool > ltFlags , gtFlags;

		for( int i=0 ; i<paramNum+2 ; i++ ) comments[i+commentNum]=new char[1024];
		sprintf( comments[commentNum++] , "Running Surface Trimmer (V5)" );
		if(              In.set ) sprintf(comments[commentNum++],"\t--%s %s" , In.name , In.value );
		if(             Out.set ) sprintf(comments[commentNum++],"\t--%s %s" , Out.name , Out.value );
		if(            Trim.set ) sprintf(comments[commentNum++],"\t--%s %f" , Trim.name , Trim.value );
		if(          Smooth.set ) sprintf(comments[commentNum++],"\t--%s %d" , Smooth.name , Smooth.value );
		if( IslandAreaRatio.set ) sprintf(comments[commentNum++],"\t--%s %f" , IslandAreaRatio.name , IslandAreaRatio.value );
		if(     PolygonMesh.set ) sprintf(comments[commentNum++],"\t--%s" , PolygonMesh.name );

		double t=Time();
		for( size_t i=0 ; i<polygons.size() ; i++ ) SplitPolygon( polygons[i] , vertices , &ltPolygons , &gtPolygons , &ltFlags , &gtFlags , vertexTable , Trim.value );
		if( IslandAreaRatio.value>0 )
		{
			std::vector< std::vector< int > > _ltPolygons , _gtPolygons;
			std::vector< std::vector< int > > ltComponents , gtComponents;
			SetConnectedComponents( ltPolygons , ltComponents );
			SetConnectedComponents( gtPolygons , gtComponents );
			std::vector< double > ltAreas( ltComponents.size() , 0. ) , gtAreas( gtComponents.size() , 0. );
			std::vector< bool > ltComponentFlags( ltComponents.size() , false ) , gtComponentFlags( gtComponents.size() , false );
			double area = 0.;
			for( size_t i=0 ; i<ltComponents.size() ; i++ )
			{
				for( size_t j=0 ; j<ltComponents[i].size() ; j++ )
				{
					ltAreas[i] += PolygonArea( vertices , ltPolygons[ ltComponents[i][j] ] );
					ltComponentFlags[i] = ( ltComponentFlags[i] || ltFlags[ ltComponents[i][j] ] );
				}
				area += ltAreas[i];
			}
			for( size_t i=0 ; i<gtComponents.size() ; i++ )
			{
				for( size_t j=0 ; j<gtComponents[i].size() ; j++ )
				{
					gtAreas[i] += PolygonArea( vertices , gtPolygons[ gtComponents[i][j] ] );
					gtComponentFlags[i] = ( gtComponentFlags[i] || gtFlags[ gtComponents[i][j] ] );
				}
				area += gtAreas[i];
			}
			for( size_t i=0 ; i<ltComponents.size() ; i++ )
			{
				if( ltAreas[i]<area*IslandAreaRatio.value && ltComponentFlags[i] ) for( size_t j=0 ; j<ltComponents[i].size() ; j++ ) _gtPolygons.push_back( ltPolygons[ ltComponents[i][j] ] );
				else                                                               for( size_t j=0 ; j<ltComponents[i].size() ; j++ ) _ltPolygons.push_back( ltPolygons[ ltComponents[i][j] ] );
			}
			for( size_t i=0 ; i<gtComponents.size() ; i++ )
			{
				if( gtAreas[i]<area*IslandAreaRatio.value && gtComponentFlags[i] ) for( size_t j=0 ; j<gtComponents[i].size() ; j++ ) _ltPolygons.push_back( gtPolygons[ gtComponents[i][j] ] );
				else                                                               for( size_t j=0 ; j<gtComponents[i].size() ; j++ ) _gtPolygons.push_back( gtPolygons[ gtComponents[i][j] ] );
			}
			ltPolygons = _ltPolygons , gtPolygons = _gtPolygons;
		}
		if( !PolygonMesh.set )
		{
			{
				std::vector< std::vector< int > > polys = ltPolygons;
				Triangulate( vertices , ltPolygons , polys ) , ltPolygons = polys;
			}
			{
				std::vector< std::vector< int > > polys = gtPolygons;
				Triangulate( vertices , gtPolygons , polys ) , gtPolygons = polys;
			}
		}

		RemoveHangingVertices( vertices , gtPolygons );
		sprintf( comments[commentNum++] , "#Trimmed In: %9.1f (s)" , Time()-t );
		if( Out.set ) PlyWritePolygons( Out.value , vertices , gtPolygons , PlyValueVertex< float >::Properties , PlyValueVertex< float >::Components , ft , comments , commentNum );
	}
	else
	{
		if( ColorRange.set ) min = ColorRange.values[0] , max = ColorRange.values[1];
		std::vector< PlyColorVertex< float > > outVertices;
		ColorVertices( vertices , outVertices , min , max );
		if( Out.set ) PlyWritePolygons( Out.value , outVertices , polygons , PlyColorVertex< float >::Properties , PlyColorVertex< float >::Components , ft , comments , commentNum );
	}

	return EXIT_SUCCESS;
}
Esempio n. 13
0
/*
=============
R_AddShadowCaster

Polygons must be added in front to back order!
=============
*/
svnode_t *R_AddShadowCaster(svnode_t *node, vec3_t *v, int vnum, msurface_t *surf,int depth) {

    int sign;
    int	signs[MAX_POLY_VERT],signs2[MAX_POLY_VERT];
    vec3_t v1[MAX_POLY_VERT],v2[MAX_POLY_VERT];
    int vnum1,vnum2;
    int i;

    if (depth > 1500) {
        Con_Printf("to deep\n");
        return NULL;
    }

    if (vnum == 0) return NULL;


    sign = 0;
    for (i=0; i<vnum; i++) {
        sign |= signs[i] = Epsilon_Sign (DotProduct (v[i], node->splitplane->normal)- node->splitplane->dist);
    }

    if (sign == 1) {

        if (node->children[0] != NULL) {

            R_AddShadowCaster (node->children[0], v, vnum, surf, depth+1);
        } else {

            svBsp_NumCutPolys++;
        }


    } else if (sign == 2) {


        if (node->children[1] != NULL) {


            R_AddShadowCaster (node->children[1], v, vnum, surf, depth+1);
        } else {

            node->children[1] = ExpandVolume(v, signs, vnum, surf);

            if (surf->visframe != r_lightTimestamp) {
                //Store it out as visible
                surf->shadowchain = shadowchain;
                surf->visframe = r_lightTimestamp;
                surf->polys->lightTimestamp = r_lightTimestamp;
                shadowchain = surf;
                svBsp_NumKeptPolys++;
            }
        }

    } else if (sign == 3) {


        SplitPolygon(&v[0], &signs[0], vnum, node->splitplane, &v1[0], &vnum1, &v2[0], &vnum2);

        if (node->children[0] != NULL) {

            R_AddShadowCaster (node->children[0], v1, vnum1, surf, depth+1);

        } else {

            svBsp_NumCutPolys++;

        }


        if (vnum2 == 0) return NULL;

        if (node->children[1] != NULL) {

            R_AddShadowCaster (node->children[1], v2, vnum2, surf, depth+1);
        } else {

            node->children[1] = ExpandVolume (v2, signs2, vnum2, surf);

            if (surf->visframe != r_lightTimestamp) {
                //Store it out as visible
                surf->shadowchain = shadowchain;
                surf->visframe = r_lightTimestamp;
                surf->polys->lightTimestamp = r_lightTimestamp;
                shadowchain = surf;
                svBsp_NumKeptPolys++;
            }
        }
    }
    return NULL;
}