Hi UT666 , all
hope this helps
This is a simple object slicer CUBE’s, Pyramids etc, it works ONLY in triangle based surfaces and NON complex objects, but is fairly easy to convert.
I pump in for pobj->Vpos the 3dtexture coords of a cube and directly render the returned poly coords to both the Vertices (Scaled) and the 3dTexCoords without the requirement for autogen.
How to use
pobj->Vpos=Vertices for object (3d cube texture coords)
pobj->Indice_Pool[surfaceNo*3 + surface indice order (only triangle surfaces)]=pobj->Vpos[^data]
Bind object to the slicer
Bind_Volume(^object)
loop
Set the Slicer Normal
Set_Volume_Slice_Normal(_array3 Vnrm)
Extract Polygon
Extract_Cap(GLfloat plane_dist) (Between Max/Min distances)
till finished with obj
Free Slicer
Free_Slicer(true)
////C++ Code
</font><blockquote><font size=“1” face=“Verdana, Arial”>code:</font><hr /><pre style=“font-size:x-small; font-family: monospace;”>
#define FreePtr(pt)
if (pt!=NULL) free(pt);
pt=NULL;
typedef GLfloat _array3[3];
typedef struct tag_SurfaceCut
{
int IndiceLinks[2][2];
bool used;
} SurfaceCut;
template<typename T>T* T_MemAlloc(unsigned int scount)
{
T *Temp;
Temp=(T *) malloc(sizeof(T)*scount);
if (Temp==NULL) return NULL;
memset(Temp,0,sizeof(T)*scount); // zero mem
return Temp;
}
class Volume_Slicer
{
public:
Volume_Slicer()
{
pobj=NULL;
Vertex_Distance=NULL;
Poly_Cap=NULL;
Edge_Links=NULL;
EdgeToEdge=NULL;
}
~Volume_Slicer()
{
Free_Slicer(true);
}
object_pool *pobj; //bind object
_array3 SliceNormal; //Surface Cut Plane Normal
GLfloat *Vertex_Distance; //ASSIGNED T_Mem
GLfloat Max_Dist,Min_Dist; //Returned Max/Min Vertex Distance to Surface Plane, based on Surface Normal
_array3 *Poly_Cap; //Returned Drawing Polygon Slice
int No_PolyVertices; //No of Vertices in Polygon
SurfaceCut *Edge_Links; //pointer to indice
int No_EdgeLinks; //etc
int *EdgeToEdge; //Edges found for cutting
int NoEdgeToEdge; //etc
void Free_Slicer(bool finished) //TRUE FINISHED WITH ALL DATA, FALSE STILL USING POBJ
{
if(finished)
{
FreePtr(Vertex_Distance);
FreePtr(Edge_Links);
pobj=NULL;
}
FreePtr(Poly_Cap);
FreePtr(EdgeToEdge);
}
bool Bind_Volume(object_pool *pobjp) //Bind object to Slicer (Only using VERTS/SURFACE INDICES)
{
if (pobjp==NULL) return false;
if (pobj!=NULL) Free_Slicer(true);
pobj=pobjp;
//create MaxPoly(vertices)buffer
Vertex_Distance=T_MemAlloc<GLfloat>(pobj->NoVertices);
if (Vertex_Distance==NULL)
{
pobj=NULL;
return false;
}
Edge_Links=T_MemAlloc<SurfaceCut>(pobj->NoSurfaces);
if (Edge_Links==NULL)
{
pobj=NULL;
free(Vertex_Distance);
return false;
}
return true;
} //error invalid pobjp, not enough mem verts or MaxPoly
int Set_Volume_Slice_Normal(_array3 Vnrm) //Set Slice Normal and dot Vertices with normal
{
if (pobj==NULL) return 0;
Vertex(SliceNormal,Vnrm);
Max_Dist=-3.4E38;
Min_Dist=3.4E38;
for (int i=0;i<pobj->NoVertices;i++)
{
Vertex_Distance[i]=DotProduct(pobj->Vpos[i],SliceNormal);
Max_Dist=get_max(Max_Dist,Vertex_Distance[i]);
Min_Dist=get_min(Min_Dist,Vertex_Distance[i]);
}
return i; //error i=0, no data or invalid pointer pobj
}
bool Extract_Cap(GLfloat plane_dist) //Creates Polygon with Min<=plane_dist<=Max
{
if (pobj==NULL) return false;
Free_Slicer(false);
GLfloat PlaneEq;
//compile edges cut
int si,vi,indxA,indxB;
int rcEL,rcSC;
rcEL=0;
for (si=0;si<pobj->NoSurfaces;si++)
{
rcSC=0;
for(vi=0;vi<3;vi++)
{
indxA=pobj->Indice_Pool[si*3+vi];
indxB=pobj->Indice_Pool[si*3+((vi+1)%3)];
PlaneEq=(Vertex_Distance[indxA]-plane_dist)*(Vertex_Distance[indxB]-plane_dist);
if (PlaneEq<=0) //Plane Cuts
{
Edge_Links[rcEL].IndiceLinks[rcSC][0]=indxA; //store vertices for edge
Edge_Links[rcEL].IndiceLinks[rcSC][1]=indxB;
Edge_Links[rcEL].used=false;
rcSC++;
}
}
if (rcSC>0) rcEL++;
}
//create linked list of indices then compute actual cuts
NoEdgeToEdge=rcEL*2;
EdgeToEdge=T_MemAlloc<int>(NoEdgeToEdge);
if (EdgeToEdge==NULL) return false;
EdgeToEdge[0]=0; //n*2 + which surface edge
EdgeToEdge[1]=1;
int inspecting,cmpA,cmpB,cmpA2,cmpB2;
inspecting=1; //rcEL 0 rcSC 1
cmpA=Edge_Links[0].IndiceLinks[1][0];
cmpB=Edge_Links[0].IndiceLinks[1][1];
Edge_Links[0].used=true;
int usedfound=1,chksum=0,EtoE=2;
bool cmpfound;
si=0;
while ((usedfound<rcEL)&&(chksum<rcEL))
{
if (Edge_Links[si].used==false)
{
cmpfound=false;
for(vi=0;vi<2;vi++)
{
cmpA2=Edge_Links[si].IndiceLinks[vi][0];
cmpB2=Edge_Links[si].IndiceLinks[vi][1];
if (((cmpA==cmpA2)&&(cmpB==cmpB2))