Beispiel #1
0
		IPoint2						mSp0;
		Point3						mP0;

	public:
		int		proc( ViewExp *vpt,int msg, int point, int flags, IPoint2 m, Matrix3& mat );
		void	SetObj(LuminaireObject *obj) { mpObject = obj; }
};

static LuminaireObjectCreateCallBack gLuminaireCreateCB;


//===========================================================================
// LuminaireObject implementation
//===========================================================================
const TCHAR LuminaireObject::mInternalClassName[] = _T("LuminaireHelper");
const Box3	LuminaireObject::mDefBoxSize(Point3(-10, -10, 0), Point3(10, 10, 20));


//---------------------------------------------------------------------------
// Constructor/Destructor
LuminaireObject::LuminaireObject() 
: mpBlock(NULL)
{ 
	GetLuminaireDesc()->MakeAutoParamBlocks(this);
	SetBox(const_cast<Box3&>(mDefBoxSize));
	dumFlags &= ~MESH_VALID;
}

LuminaireObject::~LuminaireObject() 
{ 
	DeleteAllRefsFromMe();
Beispiel #2
0
static inline Point3 pabs(Point3 p) { return Point3(fabs(p.x),fabs(p.y),fabs(p.z)); }
Beispiel #3
0
void ExtrudeMod::BuildMeshFromShape(TimeValue t,ModContext &mc, ObjectState * os, Mesh &mesh, BOOL simple) {
	BOOL texturing;
	pblock->GetValue(PB_MAPPING, TimeValue(0), texturing, FOREVER);
	BOOL genMatIDs;
	pblock->GetValue(PB_GEN_MATIDS, TimeValue(0), genMatIDs, FOREVER);
	BOOL useShapeIDs;
	pblock->GetValue(PB_USE_SHAPEIDS, TimeValue(0), useShapeIDs, FOREVER);
	BOOL smooth;
	pblock->GetValue(PB_SMOOTH, TimeValue(0), smooth, FOREVER);

	ShapeObject *shape = (ShapeObject *)os->obj;

	float amount;
	int levels,capStart,capEnd,capType;

	pblock->GetValue(PB_AMOUNT,t,amount,FOREVER);
	if(simple) {
		levels = 1;
		capStart = capEnd = FALSE;
		}
	else {
		pblock->GetValue(PB_SEGS,t,levels,FOREVER);
		if (levels<1) levels = 1;
		pblock->GetValue(PB_CAPSTART,t,capStart,FOREVER);
		pblock->GetValue(PB_CAPEND,t,capEnd,FOREVER);
		}
	pblock->GetValue(PB_CAPTYPE,t,capType,FOREVER);

	LimitValue(amount, -1000000.0f, 1000000.0f);

	// Get the basic dimension stuff
	float zSize = (float)fabs(amount);
	float baseZ = 0.0f;
	if(amount < 0.0f)
		baseZ = amount;

	// Make the shape convert itself to a PolyShape -- This makes our mesh conversion MUCH easier!
	
	PolyShape pShape;
	shape->MakePolyShape(t, pShape);
	ShapeHierarchy hier;
	pShape.OrganizeCurves(t, &hier);
	// Need to flip the reversed curves in the shape!
	pShape.Reverse(hier.reverse);

	int polys = pShape.numLines;
	int levelVerts = 0, levelFaces = 0, levelTVerts = 0;
	int verts = 0, faces = 0, tVerts = 0;
	int poly, piece;

	BOOL anyClosed = FALSE;
	for(poly = 0; poly < polys; ++poly) {
		PolyLine &line = pShape.lines[poly];
		if(!line.numPts)
			continue;
		if(line.IsClosed()) {
			anyClosed = TRUE;
			levelTVerts++;
			}
		levelVerts += line.numPts;
		levelTVerts += line.numPts;
		levelFaces += (line.Segments() * 2);
		}

	int vertsPerLevel = levelVerts;
	int numLevels = levels;

	verts = levelVerts * (levels + 1);
	tVerts = levelTVerts * (levels + 1);
	faces = levelFaces * levels;

	mesh.setNumVerts(verts);
	mesh.setNumFaces(faces);
	if(texturing) {
		mesh.setNumTVerts(tVerts);
		mesh.setNumTVFaces(faces);
		}

	// Create the vertices!
	int vert = 0;
	int tvertex = 0;
	int level;
	Point3 offset1, offset2;
	for(poly = 0; poly < polys; ++poly) {
		PolyLine &line = pShape.lines[poly];
		if(!line.numPts)
			continue;
		if(texturing) {
//DebugPrint(_T("Texture Verts:\n"));
            BOOL usePhysUVs = GetUsePhysicalScaleUVs();
			int tp;
			int texPts = line.numPts + (line.IsClosed() ? 1 : 0);
			float *texPt = new float [texPts];
			float lastPt = (float)(texPts - 1);
			float cumLen = 0.0f;
			float totLen = line.CurveLength();
			Point3 prevPt = line.pts[0].p;
			for(tp = 0; tp < texPts; ++tp) {
				int ltp = tp % line.numPts;
				if(tp == (texPts - 1))
					texPt[tp] = usePhysUVs ? totLen : 1.0f;
				else {
					Point3 &pt = line.pts[ltp].p;
					cumLen += Length(pt - prevPt);
                    if (usePhysUVs)
                        texPt[tp] = cumLen;
                    else
					texPt[tp] = cumLen / totLen;
					prevPt = pt;
					}
				}
			float flevels = (float)levels;
			for(level = 0; level <= levels; ++level) {
				float tV = (float)level / flevels;
                float vScale = usePhysUVs ? amount : 1.0f;
				for(tp = 0; tp < texPts; ++tp) {
					mesh.setTVert(tvertex++, UVVert(texPt[tp], vScale*tV, 0.0f));
					}
				}
			delete [] texPt;
			}
		int lverts = line.numPts;
		for(level = 0; level <= levels; ++level) {
			Point3 offset = Point3(0.0f, 0.0f, baseZ + (float)level / (float)levels * zSize);
			if(level == 0)
				offset1 = offset;
			else
			if(level == levels)
				offset2 = offset;
			for(int v = 0; v < lverts; ++v) {
				line.pts[v].aux = vert;			// Gives the capper this vert's location in the mesh!
				mesh.setVert(vert++, line.pts[v].p + offset);
				}
			}
		}
	assert(vert == verts);

	// If capping, do it!
	if(anyClosed && (capStart || capEnd)) {
		MeshCapInfo capInfo;
		pShape.MakeCap(t, capInfo, capType);
		// Build information for capping
		MeshCapper capper(pShape);
		if(capStart) {
			vert = 0;
			for(poly = 0; poly < polys; ++poly) {
				PolyLine &line = pShape.lines[poly];
				if(!line.numPts)
					continue;
				MeshCapPoly &capline = capper[poly];
				int lverts = line.numPts;
				for(int v = 0; v < lverts; ++v)
					capline.SetVert(v, vert++);			// Gives this vert's location in the mesh!
				vert += lverts * levels;
				}
			// Create a work matrix for grid capping
			Matrix3 gridMat = TransMatrix(offset1);
			int oldFaces = mesh.numFaces;
			capper.CapMesh(mesh, capInfo, TRUE, 16, &gridMat, genMatIDs ? -1 : 0);
			// If texturing, create the texture faces and vertices
			if(texturing)
				MakeMeshCapTexture(mesh, Inverse(gridMat), oldFaces, mesh.numFaces, GetUsePhysicalScaleUVs());
			}
		if(capEnd) {
			int baseVert = 0;
			for(poly = 0; poly < polys; ++poly) {
				PolyLine &line = pShape.lines[poly];
				if(!line.numPts)
					continue;
				MeshCapPoly &capline = capper[poly];
				int lverts = line.numPts;
				vert = baseVert + lverts * levels;
				for(int v = 0; v < lverts; ++v)
					capline.SetVert(v, vert++);			// Gives this vert's location in the mesh!
				baseVert += lverts * (levels + 1);
				}
			// Create a work matrix for grid capping
			Matrix3 gridMat = TransMatrix(offset2);
			int oldFaces = mesh.numFaces;
			capper.CapMesh(mesh, capInfo, FALSE, 16, &gridMat, genMatIDs ? -1 : 0);
			// If texturing, create the texture faces and vertices
			if(texturing)
				MakeMeshCapTexture(mesh, Inverse(gridMat), oldFaces, mesh.numFaces, GetUsePhysicalScaleUVs());
			}
		}

	// Create the faces!
	int face = 0;
	int TVface = 0;
	int baseVert = 0;
	int baseTVert = 0;
	for(poly = 0; poly < polys; ++poly) {
		PolyLine &line = pShape.lines[poly];
		if(!line.numPts)
			continue;
		int pieces = line.Segments();
		int closed = line.IsClosed();
		int segVerts = pieces + ((closed) ? 0 : 1);
		int segTVerts = pieces + 1;
		for(level = 0; level < levels; ++level) {
			int sm = 0;		// Initial smoothing group
			BOOL firstSmooth = (line.pts[0].flags & POLYPT_SMOOTH) ? TRUE : FALSE;
			for(piece = 0; piece < pieces; ++piece) {
				int v1 = baseVert + piece;
				int v2 = baseVert + ((piece + 1) % segVerts);
				int v3 = v1 + segVerts;
				int v4 = v2 + segVerts;
				// If the vertex is not smooth, go to the next group!
				BOOL thisSmooth = line.pts[piece].flags & POLYPT_SMOOTH;
				MtlID mtl = useShapeIDs ? line.pts[piece].GetMatID() : 2;
				if(piece > 0 && !thisSmooth) {
					sm++;
					if(sm > 2)
						sm = 1;
					}
				DWORD smoothGroup = 1 << sm;
				// Advance to the next smoothing group right away
				if(sm == 0)
					sm++;
				// Special case for smoothing from first segment
				if(piece == 1 && thisSmooth)
					smoothGroup |= 1;
				// Special case for smoothing from last segment
				if((piece == pieces - 1) && firstSmooth)
					smoothGroup |= 1;
				mesh.faces[face].setEdgeVisFlags(1,1,0);
				mesh.faces[face].setSmGroup(smooth ? smoothGroup : 0);
				mesh.faces[face].setMatID(genMatIDs ? mtl : 0);
				mesh.faces[face++].setVerts(v1, v2, v4);
				mesh.faces[face].setEdgeVisFlags(0,1,1);
				mesh.faces[face].setSmGroup(smooth ? smoothGroup : 0);
				mesh.faces[face].setMatID(genMatIDs ? mtl : 0);
				mesh.faces[face++].setVerts(v1, v4, v3);
//DebugPrint(_T("BV:%d V:%d v1:%d v2:%d v3:%d v4:%d\n"),baseVert, vert, v1, v2, v3, v4);
				if(texturing) {
					int tv1 = baseTVert + piece;
					int tv2 = tv1 + 1;
					int tv3 = tv1 + segTVerts;
					int tv4 = tv2 + segTVerts;
					mesh.tvFace[TVface++].setTVerts(tv1, tv2, tv4);
					mesh.tvFace[TVface++].setTVerts(tv1, tv4, tv3);
					}
				}
			baseVert += segVerts;
			baseTVert += segTVerts;
			}
		baseVert += segVerts;	// Increment to next poly start (skips last verts of this poly)
		baseTVert += segTVerts;
		}
	assert(face == faces);

	mesh.InvalidateGeomCache();
	}
Beispiel #4
0
bool Lighting::EvaluateLighting(LPDIRECT3DDEVICE9 Device, RenderMesh *RMesh, ShaderMat *Mat)
{
	D3DLIGHT9		DLight;
	D3DXVECTOR3		Pos,Dir;
	RenderLight		Light;
	int				i;

	if(!Device || !RMesh || !m_Ready)
	{
		return(false);
	}

	m_Device = Device;
	//
	//	Setup
	//
//	The force update is used when the scene is in an unknwon state - usual after a an undo of a light
	if(m_forceUpdate)
		GetLightsFromScene();

	UpdateLights();
	SetRenderStates();

//	m_Lights.clear();

	if(m_Lights.size())
	{
		for(i=0; i < m_Lights.size(); i++)
		{
			SetShader(m_Lights[i].m_Type,Mat);
			SetMaterialConst(Mat);
			SetShaderConst(i,&m_Lights[i],Mat);
			RMesh->Render(m_Device);
		}
	}
	else
	{
		m_Device->GetLight(0,&DLight);

		Light.m_Dir = Point3(-DLight.Direction.x,
							 -DLight.Direction.y,
							 -DLight.Direction.z);
				
		Light.m_Color.x	= DLight.Diffuse.r;
		Light.m_Color.y	= DLight.Diffuse.g;
		Light.m_Color.z	= DLight.Diffuse.b;

		Light.m_Pos.x	= DLight.Position.x;
		Light.m_Pos.y	= DLight.Position.y;
		Light.m_Pos.z	= DLight.Position.z;

		Light.m_InnerRange	= 1.0f;
		Light.m_OuterRange	= 1.0f / (DLight.Range * 2.0f);

		SetShader(LIGHT_DIR,Mat);
		SetMaterialConst(Mat);
		SetShaderConst(0,&Light,Mat);
		RMesh->Render(m_Device);
	}


	return(true);

}
Beispiel #5
0
Point3 SContext::DP(void)
{
	float d = (1.0f+DFACT)*(RayDiam())/(DFACT+(float)fabs(DotProd(Normal(),viewDir)));
	return Point3(d,d,d);
}
Beispiel #6
0
Point3 UVtex::EvalNormalPerturb(ShadeContext& sc) {
	return Point3(0,0,0);
}
Beispiel #7
0
//The display function that is used to display the formation.
int FormationBhvr::Display(TimeValue t, ViewExp *vpt) 
{
	if ( ! vpt || ! vpt->IsAlive() )
	{
		// why are we here
		DbgAssert(!_T("Doing Display() on invalid viewport!"));
		return FALSE;
	}

  // setup

	int i,j;
   	
	if(DisplayFormation(t)==FALSE) return FALSE;

	if(GetFollowerCount(t)<=0) return FALSE;
	if(GetFollowerMatrixCount(t)<=0) return FALSE;

	INode *leaderNode;
	leaderNode = GetLeader(t);
	if(leaderNode==NULL) return FALSE;
	
	
	//check tgo see if we have created a default sphere for drawing yet...
    //if we haven't then create it..
	if (numpts == 0) 
		GetSpherePoints(Point3(0.0f,0.0f,0.0f), 1.0, SpherePts);

	
	GraphicsWindow *gw = vpt->getGW();
   
	//set the identity matrix...
	Matrix3 idMat;
	idMat.IdentityMatrix();
    gw->setTransform(idMat);

	gw->setColor(LINE_COLOR,.815f,.976f,1.0f);

	float scaleRadius = GetDisplayScale(t);
	
	//set the drawing radius values based upon what the radius size is.
	for (i=0; i<NUMAROUND * 3; i++) ScaledPts[i] = ((SpherePts[i] * scaleRadius));
	 
	//for each follower we need to increase the bounding box by it's
	//world position location...
	for(i =0;i<GetFollowerCount(t);i++)
	{
		INode *followerNode = GetFollower(t,i);
		if(followerNode) //if we have a a node...
		{
	
			Matrix3 leaderMat = GetCurrentMatrix(leaderNode,t);
			leaderMat.NoScale();
			Matrix3 followerMat = GetFollowerMatrix(t,i);
			Matrix3 worldSpace = followerMat *leaderMat;
			for (j=0; j<NUMAROUND * 3; j++) CurPts[j] = worldSpace*ScaledPts[j]; //adding the center to the point positions
			
		   	gw->polyline(NUMAROUND,&CurPts[0],NULL,NULL,TRUE,NULL);
		 	gw->polyline(NUMAROUND,&CurPts[NUMAROUND],NULL,NULL,TRUE,NULL);
    		gw->polyline(NUMAROUND,&CurPts[NUMAROUND * 2],NULL,NULL,TRUE,NULL);

		
		}
	}

	return TRUE;
}
Beispiel #8
0
const Point3 TrigonometricCurve::operator()(const double u, Vector3 *dp_du,
    Vector3 *d2p_du2) const
//
// returns ths position of the curve at the parameter `u` (0 <= `u`
// <= 1).  If `dp_du` is not NULL, it will be set to the path
// derivative vector at `u`. If `d2p_du2` is not NULL, it will be set
// the the second path derivative vector.
//
// Note: the path derivatives are *not* normalized. If the components
// of the path had dimensions of length (i.e. the path was a
// position) and `u` had dimensions of time, the path derivatives
// `dp_du` and `d2p_du2` would be a velocity and an acceleration,
// respectively. If the caller wants a unit-length (dimensionless)
// vector, it is up to them to normalize a derivative upon its
// return.
//
{
    //
    // ASSIGNMENT (PA09)
    //
    // Enhance your previous (PA06) solution to set `*d2p_du2` to the
    // (second) path derivative as per the function header. Use your
    // knowledge of calculus to compute it.
    //
    // 15 lines in instructor solution (YMMV)
    //
    
    if (dp_du)
    {
        /*
         * Derivative is -2PI * freq * mag * sin(2PI *( freq * u + phase))  
         */

        // Derivative
        dp_du->u.g.x = -2 * M_PI * freq.u.g.x * mag.u.g.x * sin(2 * M_PI * (freq.u.g.x * u + phase.u.g.x));
        dp_du->u.g.y = -2 * M_PI * freq.u.g.y * mag.u.g.y * sin(2 * M_PI * (freq.u.g.y * u + phase.u.g.y));
        dp_du->u.g.z = -2 * M_PI * freq.u.g.z * mag.u.g.z * sin(2 * M_PI * (freq.u.g.z * u + phase.u.g.z));
    } 

	if (d2p_du2)
	{
		/*
		 * Second derivative is -4PI^2 * freq^2 * max * cos(2PI * (freq * u + phase))
		 */

		dp_du->u.g.x = (-4 * (M_PI * M_PI) * (freq.u.g.x * freq.u.g.x) * mag.u.g.x) * cos(2 * M_PI * (freq.u.g.x * u + phase.u.g.x));
        dp_du->u.g.y = (-4 * (M_PI * M_PI) * (freq.u.g.y * freq.u.g.y) * mag.u.g.y) * cos(2 * M_PI * (freq.u.g.y * u + phase.u.g.y));
        dp_du->u.g.z = (-4 * (M_PI * M_PI) * (freq.u.g.z * freq.u.g.z) * mag.u.g.z) * cos(2 * M_PI * (freq.u.g.z * u + phase.u.g.z));
	}
 

    Vec3 angle = 2 * M_PI * (freq * u + phase);

    double x = mag.u.g.x * cos(angle.u.g.x) + offset.u.g.x; 
    double y = mag.u.g.y * cos(angle.u.g.y) + offset.u.g.y; 
    double z = mag.u.g.z * cos(angle.u.g.z) + offset.u.g.z;

    Point3 value = Point3(x, y, z);

    return value; 
}
Beispiel #9
0
// Let the plug-in register itself for deferred loading
__declspec( dllexport ) ULONG CanAutoDefer()
{
	return 1;
}


/* rand returns a number between 0 and 32767 */
/* number between 0 and 1 */
const float IntMax=32767.0f;
const float IntMax1=32768.0f;
const float HalfIntMax=16383.5f;
typedef float Matrix3By3[3][3];
typedef float Matrix4By3[4][3];
Point3 Zero=Point3(0.0f,0.0f,0.0f); 

int FloatEQ0(float number)
{	return((FLOAT_EPSILON>=number)&&(number>=-FLOAT_EPSILON));}

int SmallerEQ0(float number)
{	return((SMALL_EPSILON>=number)&&(SMALL_EPSILON>=-FLOAT_EPSILON));}

int FGT0(Point3 p1)
{	return((fabs(p1[0])>SMALL_EPSILON)||(fabs(p1[1])>SMALL_EPSILON)||(fabs(p1[2])>SMALL_EPSILON));}

void Mult1X4(float *A,Matrix4By4 B,float *C)
{	C[0]=A[0]*B[0][0]+A[1]*B[1][0]+A[2]*B[2][0]+A[3]*B[3][0];
	C[1]=A[0]*B[0][1]+A[1]*B[1][1]+A[2]*B[2][1]+A[3]*B[3][1];
	C[2]=A[0]*B[0][2]+A[1]*B[1][2]+A[2]*B[2][2]+A[3]*B[3][2];
	C[3]=A[0]*B[0][3]+A[1]*B[1][3]+A[2]*B[2][3]+A[3]*B[3][3];
Beispiel #10
0
void UnwrapMod::fnAlignAndFit(int axis)
{



	//get our selection
	Box3 bounds;
	bounds.Init();
	//get the bounding box
	Point3 pnorm(0.0f,0.0f,0.0f);
	int ct = 0;
	TimeValue t = GetCOREInterface()->GetTime();
	for (int ldID = 0; ldID < mMeshTopoData.Count(); ldID++)
	{
		MeshTopoData *ld = mMeshTopoData[ldID];
		Matrix3 tm = mMeshTopoData.GetNodeTM(t,ldID);
		for (int k = 0; k < ld->GetNumberFaces(); k++) 
		{
			if (ld->GetFaceSelected(k))
			{
					// Grap the three points, xformed
				int pcount = 3;
					//				if (gfaces[k].flags & FLAG_QUAD) pcount = 4;
				pcount = ld->GetFaceDegree(k);//gfaces[k]->count;

				Point3 temp_point[4];
				for (int j=0; j<pcount; j++) 
				{
					int index = ld->GetFaceGeomVert(k,j);//gfaces[k]->t[j];
					bounds += ld->GetGeomVert(index) *tm;//gverts.d[index].p;
					if (j < 4)
						temp_point[j] = ld->GetGeomVert(index);//gverts.d[index].p;
				}
				pnorm += VectorTransform(Normalize(temp_point[1]-temp_point[0]^temp_point[2]-temp_point[1]),tm);
				ct++;
			}
		}	
	}

	if (ct == 0) return;

	theHold.Begin();
	SuspendAnimate();
	AnimateOff();

	pnorm = pnorm / (float) ct;
	Matrix3 tm(1);
	
	//if just a primary axis set the tm;
	Point3 center = bounds.Center();
		// build the scale
	Point3 scale(bounds.Width().x ,bounds.Width().y , bounds.Width().z);
	if (scale.x == 0.0f) scale.x = 1.0f;
	if (scale.y == 0.0f) scale.y = 1.0f;
 	if (scale.z == 0.0f) scale.z = 1.0f;
	
 	if (axis == 0) // x axi
	{

  		tm.SetRow(0,Point3(0.0f,-scale.y,0.0f));
		tm.SetRow(1,Point3(0.0f,0.0f,scale.z));
		tm.SetRow(2,Point3(scale.x,0.0f,0.0f));
		if ((fnGetMapMode() == PLANARMAP) || (fnGetMapMode() == PELTMAP)  || (fnGetMapMode() == SPHERICALMAP) || (fnGetMapMode() == BOXMAP))
			tm.SetRow(3,center);
		else if (fnGetMapMode() == CYLINDRICALMAP)
		{
			center.x = bounds.pmin.x;
			tm.SetRow(3,center);
		}		

		Matrix3 ptm(1), id(1);
		tm = tm ;
		SetXFormPacket tmpck(tm,ptm);
		tmControl->SetValue(t,&tmpck,TRUE,CTRL_RELATIVE);
	}
	else if (axis == 1) // y axi
	{
  		tm.SetRow(0,Point3(scale.x,0.0f,0.0f));
 		tm.SetRow(1,Point3(0.0f,0.0f,scale.z));
		tm.SetRow(2,Point3(0.0f,scale.y,0.0f));
		if ((fnGetMapMode() == PLANARMAP) || (fnGetMapMode() == PELTMAP)|| (fnGetMapMode() == SPHERICALMAP) || (fnGetMapMode() == BOXMAP))
			tm.SetRow(3,center);
		else if (fnGetMapMode() == CYLINDRICALMAP)
		{
			center.y = bounds.pmin.y;
			tm.SetRow(3,center);
		}
		

		Matrix3 ptm(1), id(1);
		tm = tm;
		SetXFormPacket tmpck(tm,ptm);
		tmControl->SetValue(t,&tmpck,TRUE,CTRL_RELATIVE);
	}
	else if (axis == 2) //z axi
	{
		tm.SetRow(0,Point3(scale.x,0.0f,0.0f));
		tm.SetRow(1,Point3(0.0f,scale.y,0.0f));
		tm.SetRow(2,Point3(0.0f,0.0f,scale.z));
		if ((fnGetMapMode() == PLANARMAP) || (fnGetMapMode() == PELTMAP)|| (fnGetMapMode() == SPHERICALMAP) || (fnGetMapMode() == BOXMAP))
			tm.SetRow(3,center);
		else if (fnGetMapMode() == CYLINDRICALMAP)
		{
			center.z = bounds.pmin.z;
			tm.SetRow(3,center);
		}
		

		Matrix3 ptm(1), id(1);
		tm = tm;
		SetXFormPacket tmpck(tm,ptm);
		tmControl->SetValue(t,&tmpck,TRUE,CTRL_RELATIVE);
	}
	else if (axis == 3) // normal
	{
		int numberOfSelectionGroups = 0;
		for (int ldID = 0; ldID < mMeshTopoData.Count(); ldID++)
		{
			MeshTopoData *ld = mMeshTopoData[ldID];
			if (ld->GetFaceSelection().NumberSet())
				numberOfSelectionGroups++;
		}
		if ((fnGetMapMode() == PLANARMAP) || (fnGetMapMode() == PELTMAP) || (numberOfSelectionGroups > 1))
		{
			//get our tm
			Matrix3 tm;
			UnwrapMatrixFromNormal(pnorm,tm);
 			Matrix3 itm = Inverse(tm);
			//find our x and y scale
			float xmax = 0.0f;
			float ymax = 0.0f;
			float zmax = 0.0f;
			Box3 localBounds;
			localBounds.Init();
			for (int ldID = 0; ldID < mMeshTopoData.Count(); ldID++)
			{
				MeshTopoData *ld = mMeshTopoData[ldID];
				Matrix3 tm = mMeshTopoData.GetNodeTM(t,ldID);
				for (int k = 0; k < ld->GetNumberFaces(); k++) 
				{
					if (ld->GetFaceSelected(k))
					{
							// Grap the three points, xformed
						int pcount = 3;
							//				if (gfaces[k].flags & FLAG_QUAD) pcount = 4;
						pcount = ld->GetFaceDegree(k);//gfaces[k]->count;

						Point3 temp_point[4];
						for (int j=0; j<pcount; j++) 
						{
							int index = ld->GetFaceGeomVert(k,j);//gfaces[k]->t[j];
							Point3 p = ld->GetGeomVert(index) * tm * itm;//gverts.d[index].p * itm;
							localBounds += p;
						}
					}
				}
			}

//			center = localBounds.Center();
			xmax = localBounds.pmax.x - localBounds.pmin.x;
			ymax = localBounds.pmax.y - localBounds.pmin.y;
			zmax = localBounds.pmax.z - localBounds.pmin.z;

			if (xmax < 0.001f)
				xmax = 1.0f;
			if (ymax < 0.001f)
				ymax = 1.0f;
			if (zmax < 0.001f)
				zmax = 1.0f;

			Point3 vec;
			vec = Normalize(tm.GetRow(0)) * xmax;
			tm.SetRow(0,vec);

			vec = Normalize(tm.GetRow(1)) * ymax;
			tm.SetRow(1,vec);

			vec = Normalize(tm.GetRow(2)) * zmax;
			tm.SetRow(2,vec);


			tm.SetRow(3,center);
			

			Matrix3 ptm(1), id(1);
			tm = tm ;
			SetXFormPacket tmpck(tm,ptm);
			tmControl->SetValue(t,&tmpck,TRUE,CTRL_RELATIVE);
		}		
		else if ((fnGetMapMode() == CYLINDRICALMAP) || (fnGetMapMode() == SPHERICALMAP)|| (fnGetMapMode() == BOXMAP))
		{

			for (int ldID = 0; ldID < mMeshTopoData.Count(); ldID++)
			{


				//get our first 2 rings
				Tab<int> openEdges;
				Tab<int> startRing;
				Tab<int> endRing;

				MeshTopoData *ld =  mMeshTopoData[ldID];

				//skip any local data that has no selections
				if (ld->GetFaceSelection().NumberSet() == 0)
					continue;

				Matrix3 nodeTM = mMeshTopoData.GetNodeTM(t,ldID);

				for (int i = 0; i < ld->GetNumberGeomEdges(); i++)//TVMaps.gePtrList.Count(); i++)
				{
					int numberSelectedFaces = 0;
					int ct = ld->GetGeomEdgeNumberOfConnectedFaces(i);//TVMaps.gePtrList[i]->faceList.Count();
					for (int j = 0; j < ct; j++)
					{
						int faceIndex = ld->GetGeomEdgeConnectedFace(i,j);//TVMaps.gePtrList[i]->faceList[j];
						if (ld->GetFaceSelected(faceIndex))//fsel[faceIndex])
							numberSelectedFaces++;
					}
					if (numberSelectedFaces == 1)
					{
						openEdges.Append(1,&i,1000);
						
					}
				}

				GetOpenEdges(ld,openEdges, startRing);
				GetOpenEdges(ld,openEdges, endRing);
				Point3 zVec = pnorm;

				Point3 centerS(0.0f,0.0f,0.0f), centerE;
				if ((startRing.Count() != 0) && (endRing.Count() != 0))
				{
					//get the center start
					Box3 BoundsS, BoundsE;
					BoundsS.Init();
					BoundsE.Init();

					//get the center end
					for (int i = 0; i < startRing.Count(); i++)
					{
						int eIndex = startRing[i];
						int a = ld->GetGeomEdgeVert(eIndex,0);//TVMaps.gePtrList[eIndex]->a;
						int b = ld->GetGeomEdgeVert(eIndex,1);//TVMaps.gePtrList[eIndex]->b;

						BoundsS += ld->GetGeomVert(a) * nodeTM;//TVMaps.geomPoints[a];
						BoundsS += ld->GetGeomVert(b) * nodeTM;//TVMaps.geomPoints[b];
					}


					for (int i = 0; i < endRing.Count(); i++)
					{
						int eIndex = endRing[i];
						int a = ld->GetGeomEdgeVert(eIndex,0);//TVMaps.gePtrList[eIndex]->a;
						int b = ld->GetGeomEdgeVert(eIndex,1);//TVMaps.gePtrList[eIndex]->b;

						BoundsE += ld->GetGeomVert(a) * nodeTM;//TVMaps.geomPoints[a];
						BoundsE += ld->GetGeomVert(b) * nodeTM;//TVMaps.geomPoints[b];
					}

					
					centerS = BoundsS.Center();
					centerE = BoundsE.Center();
					//create the vec
					zVec = centerE - centerS;

				}
				else if ((startRing.Count() != 0) && (endRing.Count() == 0))
				{
					//get the center start
					Box3 BoundsS;
					BoundsS.Init();
					

					//get the center end
					for (int i = 0; i < startRing.Count(); i++)
					{
						int eIndex = startRing[i];
						int a =  ld->GetGeomEdgeVert(eIndex,0);//TVMaps.gePtrList[eIndex]->a;
						int b =  ld->GetGeomEdgeVert(eIndex,1);//TVMaps.gePtrList[eIndex]->b;

						BoundsS += ld->GetGeomVert(a) * nodeTM;//TVMaps.geomPoints[a];
						BoundsS += ld->GetGeomVert(b) * nodeTM;//TVMaps.geomPoints[b];
					}

					centerS = BoundsS.Center();
					

					int farthestPoint= -1;
					Point3 fp;
					float farthestDist= 0.0f;
					for (int k=0; k < ld->GetNumberFaces(); k++) 
					{
						if (ld->GetFaceSelected(k))
						{
								// Grap the three points, xformed
							int pcount = 3;
								//				if (gfaces[k].flags & FLAG_QUAD) pcount = 4;
							pcount = ld->GetFaceDegree(k);//gfaces[k]->count;

							
							for (int j=0; j<pcount; j++) 
							{
								int index = ld->GetFaceGeomVert(k,j);//gfaces[k]->t[j];
								
								Point3 p = ld->GetGeomVert(index)* nodeTM;//gverts.d[index].p;
								float d = LengthSquared(p-centerS);
								if ((d > farthestDist) || (farthestPoint == -1))
								{
									farthestDist = d;
									farthestPoint = index;
									fp = p;
								}							
							}
						}
					}

					
					
					centerE = fp;
					//create the vec
					zVec = centerE - centerS;

				}
				else
				{
					zVec = Point3(0.0f,0.0f,1.0f);
				}


				//get our tm
				Matrix3 tm;
				UnwrapMatrixFromNormal(zVec,tm);
				tm.SetRow(3,centerS);
 				Matrix3 itm = Inverse(tm);
				//find our x and y scale
				float xmax = 0.0f;
				float ymax = 0.0f;
				float zmax = 0.0f;
				Box3 localBounds;
				localBounds.Init();
				for (int k = 0; k < ld->GetNumberFaces(); k++)//gfaces.Count(); k++) 
				{
					if (ld->GetFaceSelected(k))
					{
							// Grap the three points, xformed
						int pcount = 3;
							//				if (gfaces[k].flags & FLAG_QUAD) pcount = 4;
						pcount = ld->GetFaceDegree(k);//gfaces[k]->count;

						Point3 temp_point[4];
						for (int j=0; j<pcount; j++) 
						{
							int index = ld->GetFaceGeomVert(k,j);//gfaces[k]->t[j];
							Point3 p = ld->GetGeomVert(index) * nodeTM * itm;//gverts.d[index].p * itm;
							localBounds += p;
						}
					}
				}

				center = localBounds.Center() * tm;

				if (fnGetMapMode() == CYLINDRICALMAP)
				{
					if ((startRing.Count() == 0) && (endRing.Count() == 0))
					{
						centerS = center;
						centerS.z = localBounds.pmin.z;					
					}
					else
					{

						centerS = centerS * itm;
						centerS.z = localBounds.pmin.z;
						centerS = centerS * tm;
					}
				}
				else if ((fnGetMapMode() == SPHERICALMAP) || (fnGetMapMode() == BOXMAP))
				{
					centerS = center;
				}

				Point3 bc = localBounds.Center();
				bc.z = localBounds.pmin.z;
				bc = bc * tm;

				xmax = localBounds.pmax.x - localBounds.pmin.x;
				ymax = localBounds.pmax.y - localBounds.pmin.y;
				zmax = localBounds.pmax.z - localBounds.pmin.z;

				Point3 vec;
				vec = Normalize(tm.GetRow(0)) * xmax;
				tm.SetRow(0,vec);

				vec = Normalize(tm.GetRow(1)) * ymax;
				tm.SetRow(1,vec);

				vec = Normalize(tm.GetRow(2)) * zmax;
				tm.SetRow(2,vec);


				
				tm.SetRow(3,centerS);
				

				Matrix3 ptm(1), id(1);
				tm = tm;
				SetXFormPacket tmpck(tm,ptm);
				tmControl->SetValue(t,&tmpck,TRUE,CTRL_RELATIVE);
			}
			
		}
	}
	ResumeAnimate();

	if ((fnGetMapMode() == PLANARMAP) || (fnGetMapMode() == CYLINDRICALMAP) || (fnGetMapMode() == SPHERICALMAP) || (fnGetMapMode() == BOXMAP))
		ApplyGizmo();

	theHold.Accept(GetString(IDS_MAPPING_ALIGN));

	fnGetGizmoTM();

	if (ip) ip->RedrawViews(ip->GetTime());

}
Beispiel #11
0
void UnwrapMod::DrawGizmo(TimeValue t, INode* inode,/*w4 ModContext *mc, */GraphicsWindow *gw)
{
	 	ComputeSelectedFaceData();

		Matrix3 vtm(1);
		Interval iv;
		if (inode) 
			vtm = inode->GetObjectTM(t,&iv);
		Point3 a(-0.5f,-0.5f,0.0f),b(0.5f,-0.5f,0.0f),c(0.5f,0.5f,0.0f),d(-0.5f,0.5f,0.0f);
		
		Matrix3 modmat, ntm = inode->GetObjectTM(t);


		modmat = GetMapGizmoMatrix(t);

		
		gw->setTransform(modmat);	

		if ( (fnGetMapMode() == PLANARMAP) || (fnGetMapMode() == PELTMAP) )
		{
			Point3 line[5];
			line[0] =   a;
			line[1] =   b;
			line[2] =   c;
			line[3] =   d;
			line[4] = line[0];
			gw->setColor(LINE_COLOR,GetUIColor(COLOR_SEL_GIZMOS));
			gw->polyline(5, line, NULL, NULL, 0);
		}
		else if (fnGetMapMode() == CYLINDRICALMAP)
		{
			//draw the bottom circle
			int segs = 32;
			float angle = 0.0f;
			float inc = 1.0f/(float)segs * 2 * PI;
			
			Point3 prevVec;
			gw->startSegments();
	 		Point3 pl[3];
			gw->setColor(LINE_COLOR,GetUIColor(COLOR_SEL_GIZMOS));
			for (int i = 0; i < (segs+1); i++)
			{
				
				Matrix3 tm(1);
				tm.RotateZ(angle);
				Point3 vec (0.50f,0.0f,0.0f);
				
 				vec = vec * tm;
				if ( i >= 1)
				{
					pl[0] = vec;
					pl[1] = prevVec;
					gw->segment(pl,1);


					pl[0].z = 1.0f;
					pl[1].z = 1.0f;
					gw->segment(pl,1);

					if (((i%4) == 0) && (i != segs))
					{
						pl[0] = vec;
						pl[1] = vec;
						pl[1].z = 1.0f;
						gw->segment(pl,1);
					}

				}
				prevVec = vec;
				angle += inc;
			}


			Color c(openEdgeColor);
			gw->setColor(LINE_COLOR,c);
			
			pl[0] = Point3(0.50f,0.0f,0.0f);
			pl[1] = Point3(0.50f,0.0f,0.0f);
			pl[1].z = 1.0f;
			gw->segment(pl,1);

			gw->endSegments();
		}
		else if (fnGetMapMode() == SPHERICALMAP)
		{
			//draw the bottom circle
			int segs = 32;

			float inc = 1.0f/(float)segs * 2 * PI;
			
			
			gw->startSegments();
	 		Point3 pl[3];
 			Color c(openEdgeColor);
			gw->setColor(LINE_COLOR,GetUIColor(COLOR_SEL_GIZMOS));
			pl[0] = Point3(0.0f,0.0f,.6f);
			pl[1] = Point3(0.0f,0.0f,-.5f);
			gw->segment(pl,1);
			
			for (int j = 0; j < 3; j++)
			{
				float angle = 0.0f;
				Point3 prevVec;

 				gw->setColor(LINE_COLOR,GetUIColor(COLOR_SEL_GIZMOS));
				for (int i = 0; i < (segs+1); i++)
				{
					
					Matrix3 tm(1);
					Point3 vec (0.50f,0.0f,0.0f);
					if (j == 0)
						tm.RotateZ(angle);
					if (j == 1)
					{
						vec = Point3(0.0f,0.5f,0.0f);
						tm.RotateX(angle);
					}
 					if (j == 2)
					{
						vec = Point3(0.0f,0.0f,-0.5f);
						if (i < ((segs+2)/2))
							gw->setColor(LINE_COLOR,GetUIColor(COLOR_SEL_GIZMOS));
						else gw->setColor(LINE_COLOR,c);
						tm.RotateY(angle);
					}
					
					
 					vec = vec * tm;
					if ( i >= 1)
					{
						pl[0] = vec;
						pl[1] = prevVec;
						gw->segment(pl,1);

					}
					prevVec = vec;
					angle += inc;
				}
			}
			gw->endSegments();
		}
		else if (fnGetMapMode() == BOXMAP) 
		{
 			Point3 line[3];
			gw->setColor(LINE_COLOR,GetUIColor(COLOR_SEL_GIZMOS));
			gw->startSegments();

			line[0] =  Point3(-0.5f,-0.5f,-0.5f);
			line[1] =  Point3(0.5f,-0.5f,-0.5f);
			gw->segment(line,1);

			line[0] =  Point3(-0.5f,0.5f,-0.5f);
			line[1] =  Point3(0.5f,0.5f,-0.5f);
			gw->segment(line,1);

			line[0] =  Point3(0.5f,0.5f,-0.5f);
			line[1] =  Point3(0.5f,-0.5f,-0.5f);
			gw->segment(line,1);

			line[0] =  Point3(-0.5f,0.5f,-0.5f);
			line[1] =  Point3(-0.5f,-0.5f,-0.5f);
			gw->segment(line,1);




			line[0] =  Point3(-0.5f,-0.5f,0.5f);
		 	line[1] =  Point3(0.5f,-0.5f,0.5f);
			gw->segment(line,1);

			line[0] =  Point3(-0.5f,0.5f,0.5f);
			line[1] =  Point3(0.5f,0.5f,0.5f);
			gw->segment(line,1);

			line[0] =  Point3(0.5f,0.5f,0.5f);
			line[1] =  Point3(0.5f,-0.5f,0.5f);
			gw->segment(line,1);

			line[0] =  Point3(-0.5f,0.5f,0.5f);
			line[1] =  Point3(-0.5f,-0.5f,0.5f);
			gw->segment(line,1);



			line[0] =  Point3(-0.5f,-0.5f,0.5f);
			line[1] =  Point3(-0.5f,-0.5f,-0.5f);			
			gw->segment(line,1);

			line[0] =  Point3(0.5f,-0.5f,0.5f);
			line[1] =  Point3(0.5f,-0.5f,-0.5f);			
			gw->segment(line,1);

			line[0] =  Point3(-0.5f,0.5f,0.5f);
			line[1] =  Point3(-0.5f,0.5f,-0.5f);			
			gw->segment(line,1);

			line[0] =  Point3(0.5f,0.5f,0.5f);
			line[1] =  Point3(0.5f,0.5f,-0.5f);			
			gw->segment(line,1);





			

			gw->endSegments();
		}

}
Beispiel #12
0
void UnwrapMod::fnGizmoReset()
{


	
	theHold.Begin();
	SuspendAnimate();
	AnimateOff();
	TimeValue t = GetCOREInterface()->GetTime();



	
	//get our selection
	Box3 bounds;
	bounds.Init();
	//get the bounding box

	for(int ldID = 0; ldID < mMeshTopoData.Count(); ldID++)
	{
		MeshTopoData *ld = mMeshTopoData[ldID];

		Matrix3 tm = mMeshTopoData.GetNodeTM(t,ldID);

		for (int k = 0; k < ld->GetNumberFaces(); k++)//gfaces.Count(); k++) 
		{
			if (ld->GetFaceSelected(k))
			{
					// Grap the three points, xformed
				int pcount = 3;
					//				if (gfaces[k].flags & FLAG_QUAD) pcount = 4;
				pcount = ld->GetFaceDegree(k);//gfaces[k]->count;

				Point3 temp_point[4];
				for (int j=0; j<pcount; j++) 
				{
					int index = ld->GetFaceGeomVert(k,j);//gfaces[k]->t[j];
					bounds += ld->GetGeomVert(index) * tm;//gverts.d[index].p;
				}
			}
		}	

	}
	
	Matrix3 tm(1);
	
	//if just a primary axis set the tm;
	Point3 center = bounds.Center();
		// build the scale
 	Point3 scale(bounds.Width().x ,bounds.Width().y , bounds.Width().z);
	if (scale.x == 0.0f) scale.x = 1.0f;
	if (scale.y == 0.0f) scale.y = 1.0f;
 	if (scale.z == 0.0f) scale.z = 1.0f;
	float scl = scale.x;
	if (scale.y > scl) scl = scale.y;
	if (scale.z > scl) scl = scale.z;
	scale.x = scl;
	scale.y = scl;
	scale.z = scl;
	
	tm.SetRow(0,Point3(scale.x,0.0f,0.0f));
	tm.SetRow(1,Point3(0.0f,scale.y,0.0f));
	tm.SetRow(2,Point3(0.0f,0.0f,scale.z));
	if ((fnGetMapMode() == PLANARMAP) || (fnGetMapMode() == PELTMAP)|| (fnGetMapMode() == SPHERICALMAP))
		tm.SetRow(3,center);
	else if (fnGetMapMode() == CYLINDRICALMAP)
	{
		center.z = bounds.pmin.z;
		tm.SetRow(3,center);
	}
		

	Matrix3 ptm(1), id(1);
	tm = tm ;
	SetXFormPacket tmpck(tm,ptm);
	tmControl->SetValue(t,&tmpck,TRUE,CTRL_RELATIVE);
	ResumeAnimate();

	if ((fnGetMapMode() == PLANARMAP) || (fnGetMapMode() == CYLINDRICALMAP) || (fnGetMapMode() == SPHERICALMAP) || (fnGetMapMode() == BOXMAP))
		ApplyGizmo();


	theHold.Accept(GetString(IDS_MAPPING_RESET));
	fnGetGizmoTM();
	if (ip) ip->RedrawViews(ip->GetTime());

}
Beispiel #13
0
void UnwrapMod::ApplyGizmo()
{

	if ((fnGetMapMode() == PLANARMAP) || (fnGetMapMode() == PELTMAP) ||
		(fnGetMapMode() == SPHERICALMAP) || (fnGetMapMode() == CYLINDRICALMAP))
	{
		ApplyGizmoPrivate();
	}
	else
	{
  		theHold.Begin();
		//compute the center
			//get our normal list
		for (int ldID = 0; ldID < mMeshTopoData.Count(); ldID++)
		{
			MeshTopoData *ld = mMeshTopoData[ldID];
			ld->HoldFaceSel();
		}

		for (int ldID = 0; ldID < mMeshTopoData.Count(); ldID++)
		{
			MeshTopoData *ld = mMeshTopoData[ldID];
			ld->HoldFaceSel();

			Tab<Point3> fnorms;
			fnorms.SetCount(ld->GetNumberFaces());
			for (int k=0; k< fnorms.Count(); k++) 
				fnorms[k] = Point3(0.0f,0.0f,0.0f);
				
			//get our projection normal
			Point3 projectionNorm(0.0f,0.0f,0.0f);

			//build normals
			for (int k = 0; k < fnorms.Count(); k++) 
			{
				if (ld->GetFaceSelected(k))
				{
							// Grap the three points, xformed
					int pcount = 3;
					//				if (gfaces[k].flags & FLAG_QUAD) pcount = 4;
					pcount = ld->GetFaceDegree(k);//gfaces[k]->count;

					Point3 temp_point[4];
					for (int j=0; j<pcount; j++) 
					{
						int index = ld->GetFaceGeomVert(k,j);//gfaces[k]->t[j];							
						if (j < 4)
							temp_point[j] = ld->GetGeomVert(index);//gverts.d[index].p;
					}
					
					fnorms[k] = Normalize(temp_point[1]-temp_point[0]^temp_point[2]-temp_point[1]);
				}
			}
				
			BitArray front,back,left,right,top,bottom;
			front.SetSize(ld->GetNumberFaces());
			front.ClearAll();
			back = front;
			left = front;
			right = front;
			top = front;
			bottom = front;

			Tab<Point3> norms;

			Matrix3 gtm(1);
			TimeValue t = 0;
			if (ip) t = ip->GetTime();
			if (tmControl)
				tmControl->GetValue(t,&gtm,FOREVER,CTRL_RELATIVE);

			norms.SetCount(6);
			for (int i = 0; i < 3; i++)
			{
				Point3 v = gtm.GetRow(i);
				norms[i*2] = Normalize(v);
				norms[i*2+1] = norms[i*2] * -1.0f;
			}
				
			for (int k=0; k< ld->GetNumberFaces(); k++) 
			{
				if (ld->GetFaceSelected(k))
				{
					int closestFace = -1;
					float closestAngle = -10.0f;
					for (int j = 0; j < 6; j++)
					{
						float dot = DotProd(norms[j],fnorms[k]);
						if (dot > closestAngle)
						{
							closestAngle = dot;
							closestFace = j;
						}
					}
					if (closestFace == 0)
						front.Set(k,TRUE);
					else if (closestFace == 1)
						back.Set(k,TRUE);
					else if (closestFace == 2)
						left.Set(k,TRUE);
					else if (closestFace == 3)
						right.Set(k,TRUE);
					else if (closestFace == 4)
						top.Set(k,TRUE);
					else if (closestFace == 5)
						bottom.Set(k,TRUE);
				}
			}


			gtm.IdentityMatrix();
			if (tmControl)
				tmControl->GetValue(t,&gtm,FOREVER,CTRL_RELATIVE);

			Point3 xvec,yvec,zvec;
			xvec = gtm.GetRow(0);
			yvec = gtm.GetRow(1);
			zvec = gtm.GetRow(2);
  			Point3 center = gtm.GetRow(3);


			for (int k = 0; k < 6; k++)
			{

				Matrix3 tm(1);
				if (k == 0)
				{
					tm.SetRow(0,yvec);
					tm.SetRow(1,zvec);
					tm.SetRow(2,xvec);
					ld->SetFaceSelection(front);
				}
				else if (k == 1)
				{
					tm.SetRow(0,yvec);
					tm.SetRow(1,zvec);
					tm.SetRow(2,(xvec*-1.0f));

					ld->SetFaceSelection(back);
				}
				else if (k == 2)
				{
					tm.SetRow(0,xvec);
					tm.SetRow(1,zvec);
					tm.SetRow(2,yvec);

					ld->SetFaceSelection(left);
				}
				else if (k == 3)
				{
					tm.SetRow(0,xvec);
					tm.SetRow(1,zvec);
					tm.SetRow(2,(yvec *-1.0f));

					ld->SetFaceSelection(right);
				}
				else if (k == 4)
				{
					tm.SetRow(0,xvec);
					tm.SetRow(1,yvec);
					tm.SetRow(2,zvec);

					ld->SetFaceSelection(top);
				}
				else if (k == 5)
				{
					tm.SetRow(0,xvec);
					tm.SetRow(1,yvec);
					tm.SetRow(2,(zvec*-1.0f));

					ld->SetFaceSelection(bottom);
				}

				

				tm.SetRow(3,center);

				if (!fnGetNormalizeMap())
				{
					for (int i = 0; i < 3; i++)
					{
						Point3 vec = tm.GetRow(i);
						vec = Normalize(vec);
						tm.SetRow(i,vec);
					}
				}

				tm = mMeshTopoData.GetNodeTM(t,ldID) * Inverse(tm);
				ld->ApplyMap(fnGetMapMode(), fnGetNormalizeMap(), tm, this);				
			}
			ld->RestoreFaceSel();
		}

		theHold.Accept(GetString(IDS_PW_PLANARMAP));
		
	}

}
Beispiel #14
0
void LuminaireObject::BuildMesh()
{
	mesh.setNumVerts(120);
	mesh.setNumFaces(106);

	// aszabo|Feb.10.03|Compute scale of mesh. DummyObject::box has been scaled,
	// while our mDefBoxSize wasn't, but it was used to initialize the box.
	float s = box.Max().x/mDefBoxSize.Max().x;

	mesh.setVert(0, s*Point3(2.812824,-4.221277,0.000000));
	mesh.setVert(1, s*Point3(-2.731174,-4.221277,0.000000));
	mesh.setVert(2, s*Point3(-2.731174,-4.972452,0.000000));
	mesh.setVert(3, s*Point3(2.812824,-4.972452,0.000000));
	mesh.setVert(4, s*Point3(0.430951,-0.504076,0.000000));
	mesh.setVert(5, s*Point3(0.373688,-0.540217,0.000000));
	mesh.setVert(6, s*Point3(0.312884,-0.570737,0.000000));
	mesh.setVert(7, s*Point3(0.248868,-0.595212,0.000000));
	mesh.setVert(8, s*Point3(0.181967,-0.613220,0.000000));
	mesh.setVert(9, s*Point3(0.112510,-0.624335,0.000000));
	mesh.setVert(10, s*Point3(0.040825,-0.628134,0.000000));
	mesh.setVert(11, s*Point3(-0.030860,-0.624335,0.000000));
	mesh.setVert(12, s*Point3(-0.100318,-0.613220,0.000000));
	mesh.setVert(13, s*Point3(-0.167219,-0.595213,0.000000));
	mesh.setVert(14, s*Point3(-0.231235,-0.570737,0.000000));
	mesh.setVert(15, s*Point3(-0.292039,-0.540217,0.000000));
	mesh.setVert(16, s*Point3(-0.349302,-0.504076,0.000000));
	mesh.setVert(17, s*Point3(-0.402695,-0.462737,0.000000));
	mesh.setVert(18, s*Point3(-0.402695,-4.025318,0.000000));
	mesh.setVert(19, s*Point3(0.484345,-4.025318,0.000000));
	mesh.setVert(20, s*Point3(0.484345,-0.462738,0.000000));
	mesh.setVert(21, s*Point3(0.373465,-4.025318,0.000000));
	mesh.setVert(22, s*Point3(-0.291815,-4.025318,0.000000));
	mesh.setVert(23, s*Point3(-0.291815,-4.221277,0.000000));
	mesh.setVert(24, s*Point3(0.373465,-4.221277,0.000000));
	mesh.setVert(25, s*Point3(4.419012,5.754055,0.000000));
	mesh.setVert(26, s*Point3(2.964259,4.637785,0.000000));
	mesh.setVert(27, s*Point3(3.340581,4.051188,0.000000));
	mesh.setVert(28, s*Point3(3.598334,3.467271,0.000000));
	mesh.setVert(29, s*Point3(3.784944,2.884963,0.000000));
	mesh.setVert(30, s*Point3(3.947842,2.303191,0.000000));
	mesh.setVert(31, s*Point3(4.134453,1.720884,0.000000));
	mesh.setVert(32, s*Point3(4.392206,1.136967,0.000000));
	mesh.setVert(33, s*Point3(4.768528,0.550370,0.000000));
	mesh.setVert(34, s*Point3(7.900172,2.953366,0.000000));
	mesh.setVert(35, s*Point3(7.430962,3.468688,0.000000));
	mesh.setVert(36, s*Point3(6.933653,3.868786,0.000000));
	mesh.setVert(37, s*Point3(6.419484,4.199750,0.000000));
	mesh.setVert(38, s*Point3(5.899698,4.507671,0.000000));
	mesh.setVert(39, s*Point3(5.385530,4.838635,0.000000));
	mesh.setVert(40, s*Point3(4.888222,5.238734,0.000000));
	mesh.setVert(41, s*Point3(2.805657,2.557596,0.000000));
	mesh.setVert(42, s*Point3(2.664196,2.574949,0.000000));
	mesh.setVert(43, s*Point3(2.533501,2.619650,0.000000));
	mesh.setVert(44, s*Point3(2.416477,2.688673,0.000000));
	mesh.setVert(45, s*Point3(2.316031,2.778996,0.000000));
	mesh.setVert(46, s*Point3(2.235066,2.887594,0.000000));
	mesh.setVert(47, s*Point3(2.176486,3.011443,0.000000));
	mesh.setVert(48, s*Point3(2.143197,3.147520,0.000000));
	mesh.setVert(49, s*Point3(-0.028124,0.736024,0.000000));
	mesh.setVert(50, s*Point3(-0.018348,0.737188,0.000000));
	mesh.setVert(51, s*Point3(-0.008572,0.738606,0.000000));
	mesh.setVert(52, s*Point3(0.001220,0.740119,0.000000));
	mesh.setVert(53, s*Point3(0.011041,0.741571,0.000000));
	mesh.setVert(54, s*Point3(0.020906,0.742804,0.000000));
	mesh.setVert(55, s*Point3(0.030829,0.743659,0.000000));
	mesh.setVert(56, s*Point3(0.040825,0.743979,0.000000));
	mesh.setVert(57, s*Point3(0.174745,0.730856,0.000000));
	mesh.setVert(58, s*Point3(0.299803,0.693174,0.000000));
	mesh.setVert(59, s*Point3(0.413514,0.633459,0.000000));
	mesh.setVert(60, s*Point3(0.513398,0.554243,0.000000));
	mesh.setVert(61, s*Point3(0.596971,0.458053,0.000000));
	mesh.setVert(62, s*Point3(0.661752,0.347418,0.000000));
	mesh.setVert(63, s*Point3(0.705257,0.224866,0.000000));
	mesh.setVert(64, s*Point3(0.726882,0.057922,0.000000));
	mesh.setVert(65, s*Point3(0.708744,0.215121,0.000000));
	mesh.setVert(66, s*Point3(0.657090,0.359483,0.000000));
	mesh.setVert(67, s*Point3(0.576055,0.486872,0.000000));
	mesh.setVert(68, s*Point3(0.469775,0.593152,0.000000));
	mesh.setVert(69, s*Point3(0.342386,0.674188,0.000000));
	mesh.setVert(70, s*Point3(0.198024,0.725842,0.000000));
	mesh.setVert(71, s*Point3(0.040825,0.743979,0.000000));
	mesh.setVert(72, s*Point3(-0.116374,0.725842,0.000000));
	mesh.setVert(73, s*Point3(-0.260736,0.674188,0.000000));
	mesh.setVert(74, s*Point3(-0.388125,0.593152,0.000000));
	mesh.setVert(75, s*Point3(-0.494405,0.486872,0.000000));
	mesh.setVert(76, s*Point3(-0.575440,0.359483,0.000000));
	mesh.setVert(77, s*Point3(-0.627095,0.215121,0.000000));
	mesh.setVert(78, s*Point3(-0.645232,0.057922,0.000000));
	mesh.setVert(79, s*Point3(-0.627095,-0.099276,0.000000));
	mesh.setVert(80, s*Point3(-0.575440,-0.243638,0.000000));
	mesh.setVert(81, s*Point3(-0.494405,-0.371027,0.000000));
	mesh.setVert(82, s*Point3(-0.388125,-0.477308,0.000000));
	mesh.setVert(83, s*Point3(-0.260736,-0.558343,0.000000));
	mesh.setVert(84, s*Point3(-0.116374,-0.609997,0.000000));
	mesh.setVert(85, s*Point3(0.040825,-0.628134,0.000000));
	mesh.setVert(86, s*Point3(0.198024,-0.609997,0.000000));
	mesh.setVert(87, s*Point3(0.342386,-0.558343,0.000000));
	mesh.setVert(88, s*Point3(0.469775,-0.477308,0.000000));
	mesh.setVert(89, s*Point3(0.576055,-0.371027,0.000000));
	mesh.setVert(90, s*Point3(0.657090,-0.243638,0.000000));
	mesh.setVert(91, s*Point3(0.708744,-0.099276,0.000000));
	mesh.setVert(92, s*Point3(3.504380,3.242251,0.000000));
	mesh.setVert(93, s*Point3(3.486243,3.399450,0.000000));
	mesh.setVert(94, s*Point3(3.434589,3.543813,0.000000));
	mesh.setVert(95, s*Point3(3.353553,3.671200,0.000000));
	mesh.setVert(96, s*Point3(3.247273,3.777481,0.000000));
	mesh.setVert(97, s*Point3(3.119884,3.858516,0.000000));
	mesh.setVert(98, s*Point3(2.975523,3.910170,0.000000));
	mesh.setVert(99, s*Point3(2.818324,3.928308,0.000000));
	mesh.setVert(100, s*Point3(2.661125,3.910171,0.000000));
	mesh.setVert(101, s*Point3(2.516763,3.858516,0.000000));
	mesh.setVert(102, s*Point3(2.389374,3.777481,0.000000));
	mesh.setVert(103, s*Point3(2.283094,3.671201,0.000000));
	mesh.setVert(104, s*Point3(2.202058,3.543812,0.000000));
	mesh.setVert(105, s*Point3(2.150404,3.399450,0.000000));
	mesh.setVert(106, s*Point3(2.132267,3.242251,0.000000));
	mesh.setVert(107, s*Point3(2.150404,3.085053,0.000000));
	mesh.setVert(108, s*Point3(2.202059,2.940691,0.000000));
	mesh.setVert(109, s*Point3(2.283093,2.813301,0.000000));
	mesh.setVert(110, s*Point3(2.389374,2.707022,0.000000));
	mesh.setVert(111, s*Point3(2.516763,2.625986,0.000000));
	mesh.setVert(112, s*Point3(2.661125,2.574332,0.000000));
	mesh.setVert(113, s*Point3(2.818324,2.556195,0.000000));
	mesh.setVert(114, s*Point3(2.975523,2.574332,0.000000));
	mesh.setVert(115, s*Point3(3.119885,2.625987,0.000000));
	mesh.setVert(116, s*Point3(3.247273,2.707021,0.000000));
	mesh.setVert(117, s*Point3(3.353554,2.813302,0.000000));
	mesh.setVert(118, s*Point3(3.434589,2.940691,0.000000));
	mesh.setVert(119, s*Point3(3.486243,3.085052,0.000000));
	Face f;

	f.v[0] = 2;  f.v[1] = 3;  f.v[2] = 0;  	f.smGroup = 1;  f.flags = 67; mesh.faces[0] = f; 
	f.v[0] = 2;  f.v[1] = 0;  f.v[2] = 1;  	f.smGroup = 1;  f.flags = 70; mesh.faces[1] = f;
	f.v[0] = 16;  f.v[1] = 17;  f.v[2] = 18;  	f.smGroup = 1;  f.flags = 67; mesh.faces[2] = f;
	f.v[0] = 19;  f.v[1] = 20;  f.v[2] = 4;  	f.smGroup = 1;  f.flags = 67; mesh.faces[3] = f;
	f.v[0] = 15;  f.v[1] = 16;  f.v[2] = 18;  	f.smGroup = 1;  f.flags = 65; mesh.faces[4] = f;
	f.v[0] = 19;  f.v[1] = 4;  f.v[2] = 5;  	f.smGroup = 1;  f.flags = 66; mesh.faces[5] = f;
	f.v[0] = 19;  f.v[1] = 5;  f.v[2] = 6;  	f.smGroup = 1;  f.flags = 66; mesh.faces[6] = f;
	f.v[0] = 14;  f.v[1] = 15;  f.v[2] = 18;  	f.smGroup = 1;  f.flags = 65; mesh.faces[7] = f;
	f.v[0] = 13;  f.v[1] = 14;  f.v[2] = 18;  	f.smGroup = 1;  f.flags = 65; mesh.faces[8] = f;
	f.v[0] = 19;  f.v[1] = 6;  f.v[2] = 7;  	f.smGroup = 1;  f.flags = 66; mesh.faces[9] = f;
	f.v[0] = 19;  f.v[1] = 7;  f.v[2] = 8;  	f.smGroup = 1;  f.flags = 66; mesh.faces[10] = f;
	f.v[0] = 12;  f.v[1] = 13;  f.v[2] = 18;  	f.smGroup = 1;  f.flags = 65; mesh.faces[11] = f;
	f.v[0] = 18;  f.v[1] = 19;  f.v[2] = 8;  	f.smGroup = 1;  f.flags = 65; mesh.faces[12] = f;
	f.v[0] = 18;  f.v[1] = 8;  f.v[2] = 9;  	f.smGroup = 1;  f.flags = 66; mesh.faces[13] = f;
	f.v[0] = 18;  f.v[1] = 9;  f.v[2] = 10;  	f.smGroup = 1;  f.flags = 66; mesh.faces[14] = f;
	f.v[0] = 18;  f.v[1] = 10;  f.v[2] = 11;  	f.smGroup = 1;  f.flags = 66; mesh.faces[15] = f;
	f.v[0] = 12;  f.v[1] = 18;  f.v[2] = 11;  	f.smGroup = 1;  f.flags = 68; mesh.faces[16] = f;
	f.v[0] = 23;  f.v[1] = 24;  f.v[2] = 21;  	f.smGroup = 1;  f.flags = 67; mesh.faces[17] = f;
	f.v[0] = 23;  f.v[1] = 21;  f.v[2] = 22;  	f.smGroup = 1;  f.flags = 70; mesh.faces[18] = f;
	f.v[0] = 32;  f.v[1] = 33;  f.v[2] = 34;  	f.smGroup = 1;  f.flags = 67; mesh.faces[19] = f;
	f.v[0] = 32;  f.v[1] = 34;  f.v[2] = 35;  	f.smGroup = 1;  f.flags = 66; mesh.faces[20] = f;
	f.v[0] = 32;  f.v[1] = 35;  f.v[2] = 36;  	f.smGroup = 1;  f.flags = 66; mesh.faces[21] = f;
	f.v[0] = 31;  f.v[1] = 32;  f.v[2] = 36;  	f.smGroup = 1;  f.flags = 65; mesh.faces[22] = f;
	f.v[0] = 31;  f.v[1] = 36;  f.v[2] = 37;  	f.smGroup = 1;  f.flags = 66; mesh.faces[23] = f;
	f.v[0] = 30;  f.v[1] = 31;  f.v[2] = 37;  	f.smGroup = 1;  f.flags = 65; mesh.faces[24] = f;
	f.v[0] = 29;  f.v[1] = 30;  f.v[2] = 37;  	f.smGroup = 1;  f.flags = 65; mesh.faces[25] = f;
	f.v[0] = 29;  f.v[1] = 37;  f.v[2] = 38;  	f.smGroup = 1;  f.flags = 66; mesh.faces[26] = f;
	f.v[0] = 28;  f.v[1] = 29;  f.v[2] = 38;  	f.smGroup = 1;  f.flags = 65; mesh.faces[27] = f;
	f.v[0] = 28;  f.v[1] = 38;  f.v[2] = 39;  	f.smGroup = 1;  f.flags = 66; mesh.faces[28] = f;
	f.v[0] = 27;  f.v[1] = 28;  f.v[2] = 39;  	f.smGroup = 1;  f.flags = 65; mesh.faces[29] = f;
	f.v[0] = 27;  f.v[1] = 39;  f.v[2] = 40;  	f.smGroup = 1;  f.flags = 66; mesh.faces[30] = f;
	f.v[0] = 27;  f.v[1] = 40;  f.v[2] = 25;  	f.smGroup = 1;  f.flags = 66; mesh.faces[31] = f;
	f.v[0] = 27;  f.v[1] = 25;  f.v[2] = 26;  	f.smGroup = 1;  f.flags = 70; mesh.faces[32] = f;
	f.v[0] = 48;  f.v[1] = 49;  f.v[2] = 50;  	f.smGroup = 1;  f.flags = 67; mesh.faces[33] = f;
	f.v[0] = 48;  f.v[1] = 50;  f.v[2] = 51;  	f.smGroup = 1;  f.flags = 66; mesh.faces[34] = f;
	f.v[0] = 48;  f.v[1] = 51;  f.v[2] = 52;  	f.smGroup = 1;  f.flags = 66; mesh.faces[35] = f;
	f.v[0] = 48;  f.v[1] = 52;  f.v[2] = 53;  	f.smGroup = 1;  f.flags = 66; mesh.faces[36] = f;
	f.v[0] = 48;  f.v[1] = 53;  f.v[2] = 54;  	f.smGroup = 1;  f.flags = 66; mesh.faces[37] = f;
	f.v[0] = 48;  f.v[1] = 54;  f.v[2] = 55;  	f.smGroup = 1;  f.flags = 66; mesh.faces[38] = f;
	f.v[0] = 48;  f.v[1] = 55;  f.v[2] = 56;  	f.smGroup = 1;  f.flags = 66; mesh.faces[39] = f;
	f.v[0] = 48;  f.v[1] = 56;  f.v[2] = 57;  	f.smGroup = 1;  f.flags = 66; mesh.faces[40] = f;
	f.v[0] = 47;  f.v[1] = 48;  f.v[2] = 57;  	f.smGroup = 1;  f.flags = 65; mesh.faces[41] = f;
	f.v[0] = 63;  f.v[1] = 41;  f.v[2] = 42;  	f.smGroup = 1;  f.flags = 67; mesh.faces[42] = f;
	f.v[0] = 62;  f.v[1] = 63;  f.v[2] = 42;  	f.smGroup = 1;  f.flags = 65; mesh.faces[43] = f;
	f.v[0] = 47;  f.v[1] = 57;  f.v[2] = 58;  	f.smGroup = 1;  f.flags = 66; mesh.faces[44] = f;
	f.v[0] = 46;  f.v[1] = 47;  f.v[2] = 58;  	f.smGroup = 1;  f.flags = 65; mesh.faces[45] = f;
	f.v[0] = 62;  f.v[1] = 42;  f.v[2] = 43;  	f.smGroup = 1;  f.flags = 66; mesh.faces[46] = f;
	f.v[0] = 61;  f.v[1] = 62;  f.v[2] = 43;  	f.smGroup = 1;  f.flags = 65; mesh.faces[47] = f;
	f.v[0] = 46;  f.v[1] = 58;  f.v[2] = 59;  	f.smGroup = 1;  f.flags = 66; mesh.faces[48] = f;
	f.v[0] = 45;  f.v[1] = 46;  f.v[2] = 59;  	f.smGroup = 1;  f.flags = 65; mesh.faces[49] = f;
	f.v[0] = 61;  f.v[1] = 43;  f.v[2] = 44;  	f.smGroup = 1;  f.flags = 66; mesh.faces[50] = f;
	f.v[0] = 60;  f.v[1] = 61;  f.v[2] = 44;  	f.smGroup = 1;  f.flags = 65; mesh.faces[51] = f;
	f.v[0] = 45;  f.v[1] = 59;  f.v[2] = 60;  	f.smGroup = 1;  f.flags = 66; mesh.faces[52] = f;
	f.v[0] = 45;  f.v[1] = 60;  f.v[2] = 44;  	f.smGroup = 1;  f.flags = 68; mesh.faces[53] = f;
	f.v[0] = 91;  f.v[1] = 64;  f.v[2] = 65;  	f.smGroup = 1;  f.flags = 67; mesh.faces[54] = f;
	f.v[0] = 91;  f.v[1] = 65;  f.v[2] = 66;  	f.smGroup = 1;  f.flags = 66; mesh.faces[55] = f;
	f.v[0] = 90;  f.v[1] = 91;  f.v[2] = 66;  	f.smGroup = 1;  f.flags = 65; mesh.faces[56] = f;
	f.v[0] = 90;  f.v[1] = 66;  f.v[2] = 67;  	f.smGroup = 1;  f.flags = 66; mesh.faces[57] = f;
	f.v[0] = 89;  f.v[1] = 90;  f.v[2] = 67;  	f.smGroup = 1;  f.flags = 65; mesh.faces[58] = f;
	f.v[0] = 88;  f.v[1] = 89;  f.v[2] = 67;  	f.smGroup = 1;  f.flags = 65; mesh.faces[59] = f;
	f.v[0] = 88;  f.v[1] = 67;  f.v[2] = 68;  	f.smGroup = 1;  f.flags = 66; mesh.faces[60] = f;
	f.v[0] = 88;  f.v[1] = 68;  f.v[2] = 69;  	f.smGroup = 1;  f.flags = 66; mesh.faces[61] = f;
	f.v[0] = 88;  f.v[1] = 69;  f.v[2] = 70;  	f.smGroup = 1;  f.flags = 66; mesh.faces[62] = f;
	f.v[0] = 88;  f.v[1] = 70;  f.v[2] = 71;  	f.smGroup = 1;  f.flags = 66; mesh.faces[63] = f;
	f.v[0] = 88;  f.v[1] = 71;  f.v[2] = 72;  	f.smGroup = 1;  f.flags = 66; mesh.faces[64] = f;
	f.v[0] = 88;  f.v[1] = 72;  f.v[2] = 73;  	f.smGroup = 1;  f.flags = 66; mesh.faces[65] = f;
	f.v[0] = 88;  f.v[1] = 73;  f.v[2] = 74;  	f.smGroup = 1;  f.flags = 66; mesh.faces[66] = f;
	f.v[0] = 88;  f.v[1] = 74;  f.v[2] = 75;  	f.smGroup = 1;  f.flags = 66; mesh.faces[67] = f;
	f.v[0] = 88;  f.v[1] = 75;  f.v[2] = 76;  	f.smGroup = 1;  f.flags = 66; mesh.faces[68] = f;
	f.v[0] = 88;  f.v[1] = 76;  f.v[2] = 77;  	f.smGroup = 1;  f.flags = 66; mesh.faces[69] = f;
	f.v[0] = 88;  f.v[1] = 77;  f.v[2] = 78;  	f.smGroup = 1;  f.flags = 66; mesh.faces[70] = f;
	f.v[0] = 88;  f.v[1] = 78;  f.v[2] = 79;  	f.smGroup = 1;  f.flags = 66; mesh.faces[71] = f;
	f.v[0] = 88;  f.v[1] = 79;  f.v[2] = 80;  	f.smGroup = 1;  f.flags = 66; mesh.faces[72] = f;
	f.v[0] = 88;  f.v[1] = 80;  f.v[2] = 81;  	f.smGroup = 1;  f.flags = 66; mesh.faces[73] = f;
	f.v[0] = 88;  f.v[1] = 81;  f.v[2] = 82;  	f.smGroup = 1;  f.flags = 66; mesh.faces[74] = f;
	f.v[0] = 88;  f.v[1] = 82;  f.v[2] = 83;  	f.smGroup = 1;  f.flags = 66; mesh.faces[75] = f;
	f.v[0] = 88;  f.v[1] = 83;  f.v[2] = 84;  	f.smGroup = 1;  f.flags = 66; mesh.faces[76] = f;
	f.v[0] = 88;  f.v[1] = 84;  f.v[2] = 85;  	f.smGroup = 1;  f.flags = 66; mesh.faces[77] = f;
	f.v[0] = 88;  f.v[1] = 85;  f.v[2] = 86;  	f.smGroup = 1;  f.flags = 66; mesh.faces[78] = f;
	f.v[0] = 88;  f.v[1] = 86;  f.v[2] = 87;  	f.smGroup = 1;  f.flags = 70; mesh.faces[79] = f;
	f.v[0] = 105;  f.v[1] = 106;  f.v[2] = 107;  	f.smGroup = 1;  f.flags = 67; mesh.faces[80] = f;
	f.v[0] = 105;  f.v[1] = 107;  f.v[2] = 108;  	f.smGroup = 1;  f.flags = 66; mesh.faces[81] = f;
	f.v[0] = 104;  f.v[1] = 105;  f.v[2] = 108;  	f.smGroup = 1;  f.flags = 65; mesh.faces[82] = f;
	f.v[0] = 103;  f.v[1] = 104;  f.v[2] = 108;  	f.smGroup = 1;  f.flags = 65; mesh.faces[83] = f;
	f.v[0] = 103;  f.v[1] = 108;  f.v[2] = 109;  	f.smGroup = 1;  f.flags = 66; mesh.faces[84] = f;
	f.v[0] = 103;  f.v[1] = 109;  f.v[2] = 110;  	f.smGroup = 1;  f.flags = 66; mesh.faces[85] = f;
	f.v[0] = 102;  f.v[1] = 103;  f.v[2] = 110;  	f.smGroup = 1;  f.flags = 65; mesh.faces[86] = f;
	f.v[0] = 102;  f.v[1] = 110;  f.v[2] = 111;  	f.smGroup = 1;  f.flags = 66; mesh.faces[87] = f;
	f.v[0] = 102;  f.v[1] = 111;  f.v[2] = 112;  	f.smGroup = 1;  f.flags = 66; mesh.faces[88] = f;
	f.v[0] = 102;  f.v[1] = 112;  f.v[2] = 113;  	f.smGroup = 1;  f.flags = 66; mesh.faces[89] = f;
	f.v[0] = 102;  f.v[1] = 113;  f.v[2] = 114;  	f.smGroup = 1;  f.flags = 66; mesh.faces[90] = f;
	f.v[0] = 102;  f.v[1] = 114;  f.v[2] = 115;  	f.smGroup = 1;  f.flags = 66; mesh.faces[91] = f;
	f.v[0] = 102;  f.v[1] = 115;  f.v[2] = 116;  	f.smGroup = 1;  f.flags = 66; mesh.faces[92] = f;
	f.v[0] = 102;  f.v[1] = 116;  f.v[2] = 117;  	f.smGroup = 1;  f.flags = 66; mesh.faces[93] = f;
	f.v[0] = 102;  f.v[1] = 117;  f.v[2] = 118;  	f.smGroup = 1;  f.flags = 66; mesh.faces[94] = f;
	f.v[0] = 102;  f.v[1] = 118;  f.v[2] = 119;  	f.smGroup = 1;  f.flags = 66; mesh.faces[95] = f;
	f.v[0] = 102;  f.v[1] = 119;  f.v[2] = 92;  	f.smGroup = 1;  f.flags = 66; mesh.faces[96] = f;
	f.v[0] = 102;  f.v[1] = 92;  f.v[2] = 93;  	f.smGroup = 1;  f.flags = 66; mesh.faces[97] = f;
	f.v[0] = 102;  f.v[1] = 93;  f.v[2] = 94;  	f.smGroup = 1;  f.flags = 66; mesh.faces[98] = f;
	f.v[0] = 102;  f.v[1] = 94;  f.v[2] = 95;  	f.smGroup = 1;  f.flags = 66; mesh.faces[99] = f;
	f.v[0] = 102;  f.v[1] = 95;  f.v[2] = 96;  	f.smGroup = 1;  f.flags = 66; mesh.faces[100] = f;
	f.v[0] = 102;  f.v[1] = 96;  f.v[2] = 97;  	f.smGroup = 1;  f.flags = 66; mesh.faces[101] = f;
	f.v[0] = 102;  f.v[1] = 97;  f.v[2] = 98;  	f.smGroup = 1;  f.flags = 66; mesh.faces[102] = f;
	f.v[0] = 102;  f.v[1] = 98;  f.v[2] = 99;  	f.smGroup = 1;  f.flags = 66; mesh.faces[103] = f;
	f.v[0] = 102;  f.v[1] = 99;  f.v[2] = 100;  	f.smGroup = 1;  f.flags = 66; mesh.faces[104] = f;
	f.v[0] = 102;  f.v[1] = 100;  f.v[2] = 101;  	f.smGroup = 1;  f.flags = 70; mesh.faces[105] = f;
	// This makes the mesh "float" on top of other objects
	mesh.InvalidateGeomCache();
	mesh.EnableEdgeList(1);
}
Beispiel #15
0
void processFile(const char* input_filename, Config& config, GCodeExport& gcode, bool firstFile)
{
    for(unsigned int n=1; n<16;n++)
        gcode.setExtruderOffset(n, config.extruderOffset[n]);
    
    double t = getTime();
    log("Loading %s from disk...\n", input_filename);
    SimpleModel* m = loadModel(input_filename, config.matrix);
    if (!m)
    {
        log("Failed to load model: %s\n", input_filename);
        return;
    }
    log("Loaded from disk in %5.3fs\n", timeElapsed(t));
    log("Analyzing and optimizing model...\n");
    OptimizedModel* om = new OptimizedModel(m, Point3(config.objectPosition.X, config.objectPosition.Y, -config.objectSink));
    for(unsigned int v = 0; v < m->volumes.size(); v++)
    {
        log("  Face counts: %i -> %i %0.1f%%\n", (int)m->volumes[v].faces.size(), (int)om->volumes[v].faces.size(), float(om->volumes[v].faces.size()) / float(m->volumes[v].faces.size()) * 100);
        log("  Vertex counts: %i -> %i %0.1f%%\n", (int)m->volumes[v].faces.size() * 3, (int)om->volumes[v].points.size(), float(om->volumes[v].points.size()) / float(m->volumes[v].faces.size() * 3) * 100);
    }
    delete m;
    log("Optimize model %5.3fs \n", timeElapsed(t));
    //om->saveDebugSTL("c:\\models\\output.stl");
    
    log("Slicing model...\n");
    vector<Slicer*> slicerList;
    for(unsigned int volumeIdx=0; volumeIdx < om->volumes.size(); volumeIdx++)
    {
        slicerList.push_back(new Slicer(&om->volumes[volumeIdx], config.initialLayerThickness / 2, config.layerThickness, config.fixHorrible & FIX_HORRIBLE_KEEP_NONE_CLOSED, config.fixHorrible & FIX_HORRIBLE_EXTENSIVE_STITCHING));
        //slicerList[volumeIdx]->dumpSegments("C:\\models\\output.html");
    }
    log("Sliced model in %5.3fs\n", timeElapsed(t));

    SliceDataStorage storage;
    if (config.supportAngle > -1)
    {
        fprintf(stdout,"Generating support map...\n");
        generateSupportGrid(storage.support, om, config.initialLayerThickness / 2, config.layerThickness);
    }
    storage.modelSize = om->modelSize;
    storage.modelMin = om->vMin;
    storage.modelMax = om->vMax;
    delete om;
    
    log("Generating layer parts...\n");
    for(unsigned int volumeIdx=0; volumeIdx < slicerList.size(); volumeIdx++)
    {
        storage.volumes.push_back(SliceVolumeStorage());
        createLayerParts(storage.volumes[volumeIdx], slicerList[volumeIdx], config.fixHorrible & (FIX_HORRIBLE_UNION_ALL_TYPE_A | FIX_HORRIBLE_UNION_ALL_TYPE_B));
        delete slicerList[volumeIdx];
    }
    //carveMultipleVolumes(storage.volumes);
    generateMultipleVolumesOverlap(storage.volumes, config.multiVolumeOverlap);
    log("Generated layer parts in %5.3fs\n", timeElapsed(t));
    //dumpLayerparts(storage, "c:/models/output.html");
    
    const unsigned int totalLayers = storage.volumes[0].layers.size();
    for(unsigned int layerNr=0; layerNr<totalLayers; layerNr++)
    {
        for(unsigned int volumeIdx=0; volumeIdx<storage.volumes.size(); volumeIdx++)
        {
            generateInsets(&storage.volumes[volumeIdx].layers[layerNr], config.extrusionWidth, config.insetCount);
        }
        logProgress("inset",layerNr+1,totalLayers);
    }
    log("Generated inset in %5.3fs\n", timeElapsed(t));
    //dumpLayerparts(storage, "c:/models/output.html");

    for(unsigned int layerNr=0; layerNr<totalLayers; layerNr++)
    {
        for(unsigned int volumeIdx=0; volumeIdx<storage.volumes.size(); volumeIdx++)
        {
            generateSkins(layerNr, storage.volumes[volumeIdx], config.extrusionWidth, config.downSkinCount, config.upSkinCount, config.infillOverlap);
            generateSparse(layerNr, storage.volumes[volumeIdx], config.extrusionWidth, config.downSkinCount, config.upSkinCount);
        }
        logProgress("skin",layerNr+1,totalLayers);
    }
    log("Generated up/down skin in %5.3fs\n", timeElapsed(t));
    generateSkirt(storage, config.skirtDistance, config.extrusionWidth, config.skirtLineCount);
    generateRaft(storage, config.raftMargin);

    log("Generated skirt and raft in %5.3fs\n", timeElapsed(t));
    
    for(unsigned int volumeIdx=0; volumeIdx<storage.volumes.size(); volumeIdx++)
    {
        for(unsigned int layerNr=0; layerNr<totalLayers; layerNr++)
        {
            for(unsigned int partNr=0; partNr<storage.volumes[volumeIdx].layers[layerNr].parts.size(); partNr++)
            {
                if (layerNr > 0)
                    storage.volumes[volumeIdx].layers[layerNr].parts[partNr].bridgeAngle = bridgeAngle(&storage.volumes[volumeIdx].layers[layerNr].parts[partNr], &storage.volumes[volumeIdx].layers[layerNr-1]);
                else
                    storage.volumes[volumeIdx].layers[layerNr].parts[partNr].bridgeAngle = -1;
            }
        }
    }
   log("Stored volumes in %5.3fs\n", timeElapsed(t));

    gcode.setRetractionSettings(config.retractionAmount, config.retractionSpeed, config.retractionAmountExtruderSwitch);
    if (firstFile)
    {
        gcode.addCode(config.startCode);
    }else{
        gcode.resetExtrusionValue();
        gcode.addRetraction();
        gcode.setZ(maxObjectHeight + 5000);
        gcode.addMove(config.objectPosition, config.moveSpeed, 0);
    }
    gcode.addComment("total_layers=%d",totalLayers);
log("Added general info to gcode in %5.3fs\n", timeElapsed(t));

    GCodePathConfig skirtConfig(config.printSpeed, config.extrusionWidth, "SKIRT");
    GCodePathConfig inset0Config(config.printSpeed, config.extrusionWidth, "WALL-OUTER");
    GCodePathConfig inset1Config(config.printSpeed, config.extrusionWidth, "WALL-INNER");
    GCodePathConfig fillConfig(config.infillSpeed, config.extrusionWidth, "FILL");
    GCodePathConfig supportConfig(config.printSpeed, config.supportLineWidth, "SUPPORT");
    
    if (config.raftBaseThickness > 0 && config.raftInterfaceThickness > 0)
    {
        GCodePathConfig raftBaseConfig(config.initialLayerSpeed, config.raftBaseLinewidth, "SUPPORT");
        GCodePathConfig raftInterfaceConfig(config.initialLayerSpeed, config.raftInterfaceLinewidth, "SUPPORT");
        {
            gcode.addComment("LAYER:-2");
            gcode.addComment("RAFT");
            GCodePlanner gcodeLayer(gcode, config.moveSpeed);
            gcode.setZ(config.raftBaseThickness);
            gcode.setExtrusion(config.raftBaseThickness, config.filamentDiameter, config.filamentFlow);
            gcodeLayer.addPolygonsByOptimizer(storage.raftOutline, &raftBaseConfig);
            
            Polygons raftLines;
            generateLineInfill(storage.raftOutline, raftLines, config.raftBaseLinewidth, config.raftLineSpacing, config.infillOverlap, 0);
            gcodeLayer.addPolygonsByOptimizer(raftLines, &raftBaseConfig);
            
            gcodeLayer.writeGCode(false);
        }

        {
            gcode.addComment("LAYER:-1");
            gcode.addComment("RAFT");
            GCodePlanner gcodeLayer(gcode, config.moveSpeed);
            gcode.setZ(config.raftBaseThickness + config.raftInterfaceThickness);
            gcode.setExtrusion(config.raftInterfaceThickness, config.filamentDiameter, config.filamentFlow);
            
            Polygons raftLines;
            generateLineInfill(storage.raftOutline, raftLines, config.raftInterfaceLinewidth, config.raftLineSpacing, config.infillOverlap, 90);
            gcodeLayer.addPolygonsByOptimizer(raftLines, &raftInterfaceConfig);
            
            gcodeLayer.writeGCode(false);
        }
    }

    int volumeIdx = 0;
    for(unsigned int layerNr=0; layerNr<totalLayers; layerNr++)
    {
        logProgress("export", layerNr+1, totalLayers);

	log("Handling layer %u out of %u \n", layerNr+1, totalLayers);
        
        GCodePlanner gcodeLayer(gcode, config.moveSpeed);
        gcode.addComment("LAYER:%d", layerNr);
        int32_t z = config.initialLayerThickness + layerNr * config.layerThickness;
        z += config.raftBaseThickness + config.raftInterfaceThickness;
        gcode.setZ(z);
        //if (layerNr == 0)
        //    gcodeLayer.addPolygonsByOptimizer(storage.skirt, &skirtConfig);
        //log("Mark1 in %5.3fs\n", timeElapsed(t));
        for(unsigned int volumeCnt = 0; volumeCnt < storage.volumes.size(); volumeCnt++)
        {
	    log("  Going through volume %u out of %u \n", volumeCnt+1, storage.volumes.size());
            if (volumeCnt > 0)
                volumeIdx = (volumeIdx + 1) % storage.volumes.size();
            SliceLayer* layer = &storage.volumes[volumeIdx].layers[layerNr];
            gcodeLayer.setExtruder(volumeIdx);
            
            PathOptimizer partOrderOptimizer(gcode.getPositionXY());
            for(unsigned int partNr=0; partNr<layer->parts.size(); partNr++)
            {
                partOrderOptimizer.addPolygon(layer->parts[partNr].insets[0][0]);
            }
		log("partOrderOptimizer polygons %u \n", partOrderOptimizer.polygons.size());
		log("partOrderOptimizer polyorder %u \n", partOrderOptimizer.polyOrder.size());
            partOrderOptimizer.optimize();
		log("POST OPTIM partOrderOptimizer polygons %u \n", partOrderOptimizer.polygons.size());
		log("POST OPTIM partOrderOptimizer polyorder %u \n", partOrderOptimizer.polyOrder.size());
		//log("POST OPTIM polyorder at 0 %u \n", partOrderOptimizer.polyOrder[0]);
	   log("toto\n");
            
            for(unsigned int partCounter=0; partCounter<partOrderOptimizer.polyOrder.size(); partCounter++)
            {
		//log("   Going through part %u out of %u \n", partCounter+1, partOrderOptimizer.polyOrder.size());
                SliceLayerPart* part = &layer->parts[partOrderOptimizer.polyOrder[partCounter]];
                log("order index %u \n", partOrderOptimizer.polyOrder[partCounter]);
    
		try
		  {
		   if(part->skinOutline.size()>0)
			{
				if(part->skinOutline[0].size()>0)
		{
		    	Point p0 = (part->skinOutline)[0][0];
                	log("bla %f pof\n",p0.X);
}
			}
		  }
		  catch (int e)
		  {
		    log("An exception occurred. Exception Nr.%i \n",e);
		  }
		 
                /*gcodeLayer.setCombBoundary(&part->combBoundery);
                gcodeLayer.forceRetract();
                if (config.insetCount > 0)
                {
                    for(int insetNr=part->insets.size()-1; insetNr>-1; insetNr--)
                    {
                        if (insetNr == 0)
                            gcodeLayer.addPolygonsByOptimizer(part->insets[insetNr], &inset0Config);
                        else
                            gcodeLayer.addPolygonsByOptimizer(part->insets[insetNr], &inset1Config);
                    }
                }*/
                
                Polygons fillPolygons;
                int fillAngle = 45;
                if (layerNr & 1) fillAngle += 90;
                //int sparseSteps[1] = {config.extrusionWidth};
                //generateConcentricInfill(part->skinOutline, fillPolygons, sparseSteps, 1);
		log("Passing skinOutline of size %u to generator\n", (part->skinOutline).size()); 
                generateLineInfill(part->skinOutline, fillPolygons, config.extrusionWidth, config.extrusionWidth, config.infillOverlap, (part->bridgeAngle > -1) ? part->bridgeAngle : fillAngle);
                //int sparseSteps[2] = {config.extrusionWidth*5, config.extrusionWidth * 0.8};
                //generateConcentricInfill(part->sparseOutline, fillPolygons, sparseSteps, 2);
		//log("Mark1-2: after infillLineGen\n");
                if (config.sparseInfillLineDistance > 0)
                {
                    if (config.sparseInfillLineDistance > config.extrusionWidth * 4)
                    {
                        generateLineInfill(part->sparseOutline, fillPolygons, config.extrusionWidth, config.sparseInfillLineDistance * 2, config.infillOverlap, 45);
                        generateLineInfill(part->sparseOutline, fillPolygons, config.extrusionWidth, config.sparseInfillLineDistance * 2, config.infillOverlap, 45 + 90);
                    }
                    else
                    {
                        generateLineInfill(part->sparseOutline, fillPolygons, config.extrusionWidth, config.sparseInfillLineDistance, config.infillOverlap, fillAngle);
                    }
                }
		//log("Mark1-3: after before adding polygons\n");
                gcodeLayer.addPolygonsByOptimizer(fillPolygons, &fillConfig);
            }
            gcodeLayer.setCombBoundary(NULL);
        }
//log("Mark2: before supportAngle\n");
        if (config.supportAngle > -1)
        {
            SupportPolyGenerator supportGenerator(storage.support, z, config.supportAngle, config.supportEverywhere > 0, true);
            gcodeLayer.addPolygonsByOptimizer(supportGenerator.polygons, &supportConfig);
            if (layerNr == 0)
            {
                SupportPolyGenerator supportGenerator2(storage.support, z, config.supportAngle, config.supportEverywhere > 0, false);
                gcodeLayer.addPolygonsByOptimizer(supportGenerator2.polygons, &supportConfig);
            }
        }
//log("Mark2: before speedup\n");
        //Finish the layer by applying speed corrections for minimal layer times and slowdown for the initial layer.
        if (int(layerNr) < config.initialSpeedupLayers)
        {
            int n = config.initialSpeedupLayers;
            int layer0Factor = config.initialLayerSpeed * 100 / config.printSpeed;
            gcodeLayer.setSpeedFactor((layer0Factor * (n - layerNr) + 100 * (layerNr)) / n);
        }
        gcodeLayer.forceMinimalLayerTime(config.minimalLayerTime, config.minimalFeedrate);
        if (layerNr == 0)
            gcode.setExtrusion(config.initialLayerThickness, config.filamentDiameter, config.filamentFlow);
        else
            gcode.setExtrusion(config.layerThickness, config.filamentDiameter, config.filamentFlow);
	//log("Mark3: before fan on\n");
        if (int(layerNr) >= config.fanOnLayerNr)
        {
            int speed = config.fanSpeedMin;
            if (gcodeLayer.getSpeedFactor() <= 50)
            {
                speed = config.fanSpeedMax;
            }else{
                int n = gcodeLayer.getSpeedFactor() - 50;
                speed = config.fanSpeedMin * n / 50 + config.fanSpeedMax * (50 - n) / 50;
            }
            gcode.addFanCommand(speed);
        }else{
            gcode.addFanCommand(0);
        }
        //log("Finished layer in %5.3fs\n", timeElapsed(t));
        gcodeLayer.writeGCode(config.coolHeadLift > 0);
	//log("Finished writing layer in %5.3fs\n", timeElapsed(t));
    }

    /* support debug
    for(int32_t y=0; y<storage.support.gridHeight; y++)
    {
        for(int32_t x=0; x<storage.support.gridWidth; x++)
        {
            unsigned int n = x+y*storage.support.gridWidth;
            if (storage.support.grid[n].size() < 1) continue;
            int32_t z = storage.support.grid[n][0].z;
            gcode.addMove(Point3(x * storage.support.gridScale + storage.support.gridOffset.X, y * storage.support.gridScale + storage.support.gridOffset.Y, 0), 0);
            gcode.addMove(Point3(x * storage.support.gridScale + storage.support.gridOffset.X, y * storage.support.gridScale + storage.support.gridOffset.Y, z), z);
            gcode.addMove(Point3(x * storage.support.gridScale + storage.support.gridOffset.X, y * storage.support.gridScale + storage.support.gridOffset.Y, 0), 0);
        }
    }
    //*/
    
    log("Wrote layers in %5.2fs.\n", timeElapsed(t));
    gcode.tellFileSize();
    gcode.addFanCommand(0);

    logProgress("process", 1, 1);
    log("Total time elapsed %5.2fs.\n", timeElapsed(t,true));
    
    //Store the object height for when we are printing multiple objects, as we need to clear every one of them when moving to the next position.
    maxObjectHeight = std::max(maxObjectHeight, storage.modelSize.z);
}
Beispiel #16
0
BOOL plDistributor::IConformBase(Matrix3& l2w, int iRepNode, plMeshCacheTab& cache, int& iCache) const
{
    Matrix3 OTM = IOTM(iRepNode);
    Mesh* mesh = cache[iRepNode].fMesh;

    Point3 dir = l2w.VectorTransform(Point3(0.f, 0.f, 1.f));
    dir = FNormalize(dir);

    const float kOneOverSqrt2 = 0.707107f;
    Point3 scalePt(kOneOverSqrt2, kOneOverSqrt2, 0.f);
    scalePt = l2w.VectorTransform(scalePt);
    float maxScaledDist = fMaxConform * scalePt.Length();

    Box3 bnd = mesh->getBoundingBox() * OTM;
    bnd = Box3(Point3(bnd.Min().x, bnd.Min().y, -bnd.Max().z), bnd.Max());
    bnd = bnd * l2w;
    Tab<int32_t> faces;
    IFindFaceSet(bnd, faces);

    // l2w, iRepNode, cache, &iCache, maxScaledDist, dir
    iCache = cache.Count();
    cache.SetCount(iCache + 1);
    cache[iCache] = cache[iRepNode];
    cache[iCache].fMesh = new Mesh(*mesh);

    mesh = cache[iCache].fMesh;

    Matrix3 v2w = OTM * l2w;
    Matrix3 w2v = Inverse(v2w);


    float maxZ = (mesh->getBoundingBox() * OTM).Max().z;

    BOOL retVal = true;
    int i;
    for( i = 0; i < mesh->getNumVerts(); i++ )
    {
        Point3 pt = mesh->getVert(i) * OTM;

        const float kMaxConformZ = 0.5f;
        if( pt.z < kMaxConformZ )
        {
            pt.z = 0;

            pt = pt * l2w;

            Point3 projPt;
            if( !IProjectVertex(pt, dir, maxScaledDist, faces, projPt) )
            {
                retVal = false;
                break;
            }

            Point3 del = w2v.VectorTransform(projPt - pt);
            mesh->getVert(i) += del;
        }
    }
    if( !retVal )
    {
        delete cache[iCache].fMesh;
        cache.SetCount(iCache);
        iCache = iRepNode;
    }
    return retVal;
}
Beispiel #17
0
void processFile(const char* input_filename, ConfigSettings& config, GCodeExport& gcode, bool firstFile)
{
    for(unsigned int n=1; n<16;n++)
        gcode.setExtruderOffset(n, config.extruderOffset[n].p());
    gcode.setFlavor(config.gcodeFlavor);
    
    double t = getTime();
    log("Loading %s from disk...\n", input_filename);
    SimpleModel* m = loadModel(input_filename, config.matrix);
    if (!m)
    {
        log("Failed to load model: %s\n", input_filename);
        return;
    }
    log("Loaded from disk in %5.3fs\n", timeElapsed(t));
    log("Analyzing and optimizing model...\n");
    OptimizedModel* om = new OptimizedModel(m, Point3(config.objectPosition.X, config.objectPosition.Y, -config.objectSink));
    for(unsigned int v = 0; v < m->volumes.size(); v++)
    {
        log("  Face counts: %i -> %i %0.1f%%\n", (int)m->volumes[v].faces.size(), (int)om->volumes[v].faces.size(), float(om->volumes[v].faces.size()) / float(m->volumes[v].faces.size()) * 100);
        log("  Vertex counts: %i -> %i %0.1f%%\n", (int)m->volumes[v].faces.size() * 3, (int)om->volumes[v].points.size(), float(om->volumes[v].points.size()) / float(m->volumes[v].faces.size() * 3) * 100);
    }
    delete m;
    log("Optimize model %5.3fs \n", timeElapsed(t));
    //om->saveDebugSTL("c:\\models\\output.stl");
    
    log("Slicing model...\n");
    vector<Slicer*> slicerList;
    for(unsigned int volumeIdx=0; volumeIdx < om->volumes.size(); volumeIdx++)
    {
        slicerList.push_back(new Slicer(&om->volumes[volumeIdx], config.initialLayerThickness / 2, config.layerThickness, config.fixHorrible & FIX_HORRIBLE_KEEP_NONE_CLOSED, config.fixHorrible & FIX_HORRIBLE_EXTENSIVE_STITCHING));
        //slicerList[volumeIdx]->dumpSegments("C:\\models\\output.html");
    }
    log("Sliced model in %5.3fs\n", timeElapsed(t));

    SliceDataStorage storage;
    if (config.supportAngle > -1)
    {
        fprintf(stdout,"Generating support map...\n");
        generateSupportGrid(storage.support, om);
    }
    storage.modelSize = om->modelSize;
    storage.modelMin = om->vMin;
    storage.modelMax = om->vMax;
    delete om;
    
    log("Generating layer parts...\n");
    for(unsigned int volumeIdx=0; volumeIdx < slicerList.size(); volumeIdx++)
    {
        storage.volumes.push_back(SliceVolumeStorage());
        createLayerParts(storage.volumes[volumeIdx], slicerList[volumeIdx], config.fixHorrible & (FIX_HORRIBLE_UNION_ALL_TYPE_A | FIX_HORRIBLE_UNION_ALL_TYPE_B));
        delete slicerList[volumeIdx];
    }
    //carveMultipleVolumes(storage.volumes);
    generateMultipleVolumesOverlap(storage.volumes, config.multiVolumeOverlap);
    log("Generated layer parts in %5.3fs\n", timeElapsed(t));
    //dumpLayerparts(storage, "c:/models/output.html");
    
    const unsigned int totalLayers = storage.volumes[0].layers.size();
    for(unsigned int layerNr=0; layerNr<totalLayers; layerNr++)
    {
        for(unsigned int volumeIdx=0; volumeIdx<storage.volumes.size(); volumeIdx++)
        {
            generateInsets(&storage.volumes[volumeIdx].layers[layerNr], config.extrusionWidth, config.insetCount);
        }
        logProgress("inset",layerNr+1,totalLayers);
    }
    log("Generated inset in %5.3fs\n", timeElapsed(t));
    //dumpLayerparts(storage, "c:/models/output.html");

    for(unsigned int layerNr=0; layerNr<totalLayers; layerNr++)
    {
        for(unsigned int volumeIdx=0; volumeIdx<storage.volumes.size(); volumeIdx++)
        {
            generateSkins(layerNr, storage.volumes[volumeIdx], config.extrusionWidth, config.downSkinCount, config.upSkinCount, config.infillOverlap);
            generateSparse(layerNr, storage.volumes[volumeIdx], config.extrusionWidth, config.downSkinCount, config.upSkinCount);
        }
        logProgress("skin",layerNr+1,totalLayers);
    }
    log("Generated up/down skin in %5.3fs\n", timeElapsed(t));
    generateSkirt(storage, config.skirtDistance, config.extrusionWidth, config.skirtLineCount, config.skirtMinLength);
    generateRaft(storage, config.raftMargin, config.supportAngle, config.supportEverywhere > 0, config.supportXYDistance);
    
    for(unsigned int volumeIdx=0; volumeIdx<storage.volumes.size(); volumeIdx++)
    {
        for(unsigned int layerNr=0; layerNr<totalLayers; layerNr++)
        {
            for(unsigned int partNr=0; partNr<storage.volumes[volumeIdx].layers[layerNr].parts.size(); partNr++)
            {
                if (layerNr > 0)
                    storage.volumes[volumeIdx].layers[layerNr].parts[partNr].bridgeAngle = bridgeAngle(&storage.volumes[volumeIdx].layers[layerNr].parts[partNr], &storage.volumes[volumeIdx].layers[layerNr-1]);
                else
                    storage.volumes[volumeIdx].layers[layerNr].parts[partNr].bridgeAngle = -1;
            }
        }
    }

    gcode.setRetractionSettings(config.retractionAmount, config.retractionSpeed, config.retractionAmountExtruderSwitch, config.minimalExtrusionBeforeRetraction);
    if (firstFile)
    {
        if (gcode.getFlavor() == GCODE_FLAVOR_ULTIGCODE)
        {
            gcode.addCode(";FLAVOR:UltiGCode");
            gcode.addCode(";TIME:<__TIME__>");
            gcode.addCode(";MATERIAL:<FILAMENT>");
        }
        gcode.addCode(config.startCode);
    }else{
        gcode.addFanCommand(0);
        gcode.resetExtrusionValue();
        gcode.addRetraction();
        gcode.setZ(maxObjectHeight + 5000);
        gcode.addMove(Point(storage.modelMin.x, storage.modelMin.y), config.moveSpeed, 0);
    }
    gcode.addComment("total_layers=%d",totalLayers);

    GCodePathConfig skirtConfig(config.printSpeed, config.extrusionWidth, "SKIRT");
    GCodePathConfig inset0Config(config.printSpeed, config.extrusionWidth, "WALL-OUTER");
    GCodePathConfig inset1Config(config.printSpeed, config.extrusionWidth, "WALL-INNER");
    GCodePathConfig fillConfig(config.infillSpeed, config.extrusionWidth, "FILL");
    GCodePathConfig supportConfig(config.printSpeed, config.extrusionWidth, "SUPPORT");
    
    if (config.raftBaseThickness > 0 && config.raftInterfaceThickness > 0)
    {
        GCodePathConfig raftBaseConfig(config.initialLayerSpeed, config.raftBaseLinewidth, "SUPPORT");
        GCodePathConfig raftInterfaceConfig(config.initialLayerSpeed, config.raftInterfaceLinewidth, "SUPPORT");
        {
            gcode.addComment("LAYER:-2");
            gcode.addComment("RAFT");
            GCodePlanner gcodeLayer(gcode, config.moveSpeed, config.retractionMinimalDistance);
            gcode.setZ(config.raftBaseThickness);
            gcode.setExtrusion(config.raftBaseThickness, config.filamentDiameter, config.filamentFlow);
            gcodeLayer.addPolygonsByOptimizer(storage.raftOutline, &raftBaseConfig);
            
            Polygons raftLines;
            generateLineInfill(storage.raftOutline, raftLines, config.raftBaseLinewidth, config.raftLineSpacing, config.infillOverlap, 0);
            gcodeLayer.addPolygonsByOptimizer(raftLines, &raftBaseConfig);
            
            gcodeLayer.writeGCode(false);
        }

        {
            gcode.addComment("LAYER:-1");
            gcode.addComment("RAFT");
            GCodePlanner gcodeLayer(gcode, config.moveSpeed, config.retractionMinimalDistance);
            gcode.setZ(config.raftBaseThickness + config.raftInterfaceThickness);
            gcode.setExtrusion(config.raftInterfaceThickness, config.filamentDiameter, config.filamentFlow);
            
            Polygons raftLines;
            generateLineInfill(storage.raftOutline, raftLines, config.raftInterfaceLinewidth, config.raftLineSpacing, config.infillOverlap, 90);
            gcodeLayer.addPolygonsByOptimizer(raftLines, &raftInterfaceConfig);
            
            gcodeLayer.writeGCode(false);
        }
    }

    int volumeIdx = 0;
    for(unsigned int layerNr=0; layerNr<totalLayers; layerNr++)
    {
        logProgress("export", layerNr+1, totalLayers);
        
        GCodePlanner gcodeLayer(gcode, config.moveSpeed, config.retractionMinimalDistance);
        gcode.addComment("LAYER:%d", layerNr);
        int32_t z = config.initialLayerThickness + layerNr * config.layerThickness;
        z += config.raftBaseThickness + config.raftInterfaceThickness;
        gcode.setZ(z);
        if (layerNr == 0)
            gcodeLayer.addPolygonsByOptimizer(storage.skirt, &skirtConfig);
        
        for(unsigned int volumeCnt = 0; volumeCnt < storage.volumes.size(); volumeCnt++)
        {
            if (volumeCnt > 0)
                volumeIdx = (volumeIdx + 1) % storage.volumes.size();
            SliceLayer* layer = &storage.volumes[volumeIdx].layers[layerNr];
            gcodeLayer.setExtruder(volumeIdx);
            
            PathOptimizer partOrderOptimizer(gcode.getPositionXY());
            for(unsigned int partNr=0; partNr<layer->parts.size(); partNr++)
            {
                partOrderOptimizer.addPolygon(layer->parts[partNr].insets[0][0]);
            }
            partOrderOptimizer.optimize();
            
            for(unsigned int partCounter=0; partCounter<partOrderOptimizer.polyOrder.size(); partCounter++)
            {
                SliceLayerPart* part = &layer->parts[partOrderOptimizer.polyOrder[partCounter]];
                
                if (config.enableCombing)
                    gcodeLayer.setCombBoundary(&part->combBoundery);
                else
                    gcodeLayer.setAlwaysRetract(true);
                gcodeLayer.forceRetract();
                if (config.insetCount > 0)
                {
                    for(int insetNr=part->insets.size()-1; insetNr>-1; insetNr--)
                    {
                        if (insetNr == 0)
                            gcodeLayer.addPolygonsByOptimizer(part->insets[insetNr], &inset0Config);
                        else
                            gcodeLayer.addPolygonsByOptimizer(part->insets[insetNr], &inset1Config);
                    }
                }
                
                Polygons fillPolygons;
                int fillAngle = 45;
                if (layerNr & 1) fillAngle += 90;
                //int sparseSteps[1] = {config.extrusionWidth};
                //generateConcentricInfill(part->skinOutline, fillPolygons, sparseSteps, 1);
                generateLineInfill(part->skinOutline, fillPolygons, config.extrusionWidth, config.extrusionWidth, config.infillOverlap, (part->bridgeAngle > -1) ? part->bridgeAngle : fillAngle);
                //int sparseSteps[2] = {config.extrusionWidth*5, config.extrusionWidth * 0.8};
                //generateConcentricInfill(part->sparseOutline, fillPolygons, sparseSteps, 2);
                if (config.sparseInfillLineDistance > 0)
                {
                    if (config.sparseInfillLineDistance > config.extrusionWidth * 4)
                    {
                        generateLineInfill(part->sparseOutline, fillPolygons, config.extrusionWidth, config.sparseInfillLineDistance * 2, config.infillOverlap, 45);
                        generateLineInfill(part->sparseOutline, fillPolygons, config.extrusionWidth, config.sparseInfillLineDistance * 2, config.infillOverlap, 45 + 90);
                    }
                    else
                    {
                        generateLineInfill(part->sparseOutline, fillPolygons, config.extrusionWidth, config.sparseInfillLineDistance, config.infillOverlap, fillAngle);
                    }
                }

                gcodeLayer.addPolygonsByOptimizer(fillPolygons, &fillConfig);
                
                //After a layer part, make sure the nozzle is inside the comb boundary, so we do not retract on the perimeter.
                gcodeLayer.moveInsideCombBoundary();
            }
            gcodeLayer.setCombBoundary(NULL);
        }
        if (config.supportAngle > -1)
        {
            if (config.supportExtruder > -1)
                gcodeLayer.setExtruder(config.supportExtruder);
            SupportPolyGenerator supportGenerator(storage.support, z, config.supportAngle, config.supportEverywhere > 0, config.supportXYDistance, config.supportZDistance);
            ClipperLib::Clipper supportClipper;
            supportClipper.AddPolygons(supportGenerator.polygons, ClipperLib::ptSubject);
            for(unsigned int volumeCnt = 0; volumeCnt < storage.volumes.size(); volumeCnt++)
            {
                SliceLayer* layer = &storage.volumes[volumeIdx].layers[layerNr];
                Polygons polys;
                for(unsigned int n=0; n<layer->parts.size(); n++)
                    for(unsigned int m=0; m<layer->parts[n].outline.size(); m++)
                        polys.push_back(layer->parts[n].outline[m]);
                ClipperLib::OffsetPolygons(polys, polys, config.supportXYDistance, ClipperLib::jtSquare, 2, false);
                supportClipper.AddPolygons(polys, ClipperLib::ptClip);
            }
            supportClipper.Execute(ClipperLib::ctDifference, supportGenerator.polygons);
            
            Polygons supportLines;
            if (config.supportLineDistance > 0)
            {
                if (config.supportLineDistance > config.extrusionWidth * 4)
                {
                    generateLineInfill(supportGenerator.polygons, supportLines, config.extrusionWidth, config.supportLineDistance*2, config.infillOverlap, 0);
                    generateLineInfill(supportGenerator.polygons, supportLines, config.extrusionWidth, config.supportLineDistance*2, config.infillOverlap, 90);
                }else{
                    generateLineInfill(supportGenerator.polygons, supportLines, config.extrusionWidth, config.supportLineDistance, config.infillOverlap, (layerNr & 1) ? 0 : 90);
                }
            }
            
            gcodeLayer.addPolygonsByOptimizer(supportGenerator.polygons, &supportConfig);
            gcodeLayer.addPolygonsByOptimizer(supportLines, &supportConfig);
        }

        //Finish the layer by applying speed corrections for minimal layer times and slowdown for the initial layer.
        if (int(layerNr) < config.initialSpeedupLayers)
        {
            int n = config.initialSpeedupLayers;
            int layer0Factor = config.initialLayerSpeed * 100 / config.printSpeed;
            gcodeLayer.setExtrudeSpeedFactor((layer0Factor * (n - layerNr) + 100 * (layerNr)) / n);
        }
        gcodeLayer.forceMinimalLayerTime(config.minimalLayerTime, config.minimalFeedrate);
        if (layerNr == 0)
            gcode.setExtrusion(config.initialLayerThickness, config.filamentDiameter, config.filamentFlow);
        else
            gcode.setExtrusion(config.layerThickness, config.filamentDiameter, config.filamentFlow);
        if (int(layerNr) >= config.fanOnLayerNr)
        {
            int speed = config.fanSpeedMin;
            if (gcodeLayer.getExtrudeSpeedFactor() <= 50)
            {
                speed = config.fanSpeedMax;
            }else{
                int n = gcodeLayer.getExtrudeSpeedFactor() - 50;
                speed = config.fanSpeedMin * n / 50 + config.fanSpeedMax * (50 - n) / 50;
            }
            gcode.addFanCommand(speed);
        }else{
            gcode.addFanCommand(0);
        }
        gcodeLayer.writeGCode(config.coolHeadLift > 0);
    }

    /* support debug
    for(int32_t y=0; y<storage.support.gridHeight; y++)
    {
        for(int32_t x=0; x<storage.support.gridWidth; x++)
        {
            unsigned int n = x+y*storage.support.gridWidth;
            if (storage.support.grid[n].size() < 1) continue;
            int32_t z = storage.support.grid[n][0].z;
            gcode.addMove(Point3(x * storage.support.gridScale + storage.support.gridOffset.X, y * storage.support.gridScale + storage.support.gridOffset.Y, 0), 0);
            gcode.addMove(Point3(x * storage.support.gridScale + storage.support.gridOffset.X, y * storage.support.gridScale + storage.support.gridOffset.Y, z), z);
            gcode.addMove(Point3(x * storage.support.gridScale + storage.support.gridOffset.X, y * storage.support.gridScale + storage.support.gridOffset.Y, 0), 0);
        }
    }
    //*/
    
    log("Wrote layers in %5.2fs.\n", timeElapsed(t));
    gcode.tellFileSize();
    gcode.addFanCommand(0);

    logProgress("process", 1, 1);
    log("Total time elapsed %5.2fs.\n", timeElapsed(t,true));
    
    //Store the object height for when we are printing multiple objects, as we need to clear every one of them when moving to the next position.
    maxObjectHeight = std::max(maxObjectHeight, storage.modelSize.z);
}
Beispiel #18
0
// Generate local to world from face info (pos, normal, etc)
Matrix3 plDistributor::IGenerateTransform(int iRepNode, int iFace, const Point3& pt, const Point3& bary) const
{
    const float kMinVecLengthSq = 1.e-6f;
    Matrix3 l2w(true);

    // First, set the scale
    Point3 scale;
    switch( fScaleLock )
    {
    case kLockX | kLockY:
        scale.x = fRand.RandRangeF(fScaleLo.x, fScaleHi.x);
        scale.y = scale.x;
        scale.z = fRand.RandRangeF(fScaleLo.z, fScaleHi.z);
        break;
    case kLockX | kLockY | kLockZ:
        scale.x = fRand.RandRangeF(fScaleLo.x, fScaleHi.x);
        scale.y = scale.z = scale.x;
        break;
    default:
        scale.x = fRand.RandRangeF(fScaleLo.x, fScaleHi.x);
        scale.y = fRand.RandRangeF(fScaleLo.y, fScaleHi.y);
        scale.z = fRand.RandRangeF(fScaleLo.z, fScaleHi.z);
        break;
    }

    l2w.Scale(scale);

    // Next up, get the rotation.
    // First we'll randomly rotate about local Z
    float azimRot = fRand.RandMinusOneToOne() * fAzimuthRange;
    Matrix3 azimMat;
    azimMat.SetRotateZ(azimRot);

    l2w = l2w * azimMat;

    // Now align with the surface.
    // Get the interpolated surface normal.
    Point3 surfNorm = IGetSurfaceNormal(iFace, bary);

    Matrix3 repNodeTM = fRepNodes[iRepNode]->GetNodeTM(TimeValue(0));

    Point3 alignVec = repNodeTM.GetRow(2);
    alignVec = alignVec * fWorldToSurfVec;
    alignVec = FNormalize(alignVec);

    Point3 norm = surfNorm + (alignVec - surfNorm) * fAlignWgt;
    // The norm can come out of this zero length, if the surace normal
    // is directly opposite the "natural" up direction and the weight
    // is 50% (for example). In that case, this is just a bad place
    // to drop this replicant.
    if( norm.LengthSquared() < kMinVecLengthSq )
    {
        l2w.IdentityMatrix();
        return l2w;
    }
    norm = norm.Normalize();

    // Randomize through the cone around that.
    Point3 rndNorm = norm;
    Point3 rndDir = IPerpAxis(norm);
    Point3 rndOut = rndDir ^ norm;
    rndDir *= fRand.RandMinusOneToOne();
    float len = sqrt(1.f - rndDir.LengthSquared());
    rndOut *= len;
    if( fRand.RandMinusOneToOne() < 0 )
        rndOut *= -1.f;
    Point3 rndPol = rndDir + rndOut;

    float polScale = fRand.RandZeroToOne() * fTanPolarRange;

    // Combine using the bunching factor
    polScale = polScale * (1.f - fPolarBunch) + polScale * polScale * fPolarBunch;

    rndPol *= polScale;
    rndNorm += rndPol;
    norm = rndNorm.Normalize();

    // Have "up" alignment, now just generate random dir vector perpindicular to up
    Point3 dir = repNodeTM.GetRow(1);
    dir = dir * fWorldToSurfVec;
    Point3 out = dir ^ norm;
    if( out.LengthSquared() < kMinVecLengthSq )
    {
        if( fAzimuthRange < M_PI * 0.5f )
        {
            l2w.IdentityMatrix();
            return l2w;
        }
        else
        {
            dir = IPerpAxis(norm);
            out = dir ^ norm;
        }
    }
    out = FNormalize(out);
    dir = norm ^ out;

    // If our "up" direction points into the surface, return an "up" direction
    // tangent to the surface. Also, make the "dir" direction point out from
    // the surface. So if the alignVec/fAlignWgt turns the replicant around
    // to penetrate the surface, it just lies down instead.
    //
    // There's an early out here, for the case where the surface normal is
    // exactly opposed to the destination normal. This usually means the
    // surface normal is directly opposite the alignVec. In that
    // case, we just want to bag it.
    if( DotProd(norm, surfNorm) < 0 )
    {
        dir = surfNorm;
        dir = dir.Normalize();
        out = dir ^ norm;
        if( out.LengthSquared() < kMinVecLengthSq )
        {
            l2w.IdentityMatrix();
            return l2w;
        }
        out = out.Normalize();
        norm = out ^ dir;
    }

    Matrix3 align;
    align.Set(out, dir, norm, Point3(0,0,0));

    l2w = l2w * align;


    // Lastly, set the position.
    Point3 pos = pt;
    const float offset = fRand.RandRangeF(fOffsetMin, fOffsetMax);
    pos += norm * offset;
    l2w.Translate(pos);

    l2w = l2w * fSurfNode->GetObjectTM(TimeValue(0));

    return l2w;
}
Beispiel #19
0

	FormationBhvr::follower_matrix1,	_T("formationMatrices"), TYPE_POINT3_TAB,  0,	P_VARIABLE_SIZE, IDS_OBJECTS,
		p_end,	
	FormationBhvr::follower_matrix2,	_T("formationMatrices"), TYPE_POINT3_TAB,  0,	P_VARIABLE_SIZE, IDS_OBJECTS,
		p_end,		
	FormationBhvr::follower_matrix3,	_T("formationMatrices"), TYPE_POINT3_TAB,  0,	P_VARIABLE_SIZE, IDS_OBJECTS,
		p_end,	
	FormationBhvr::follower_matrix4,	_T("formationMatrices"), TYPE_POINT3_TAB,  0,	P_VARIABLE_SIZE, IDS_OBJECTS,
		p_end,
	FormationBhvr::display_formation,		_T("displayFormation"),	TYPE_BOOL, P_RESET_DEFAULT, IDS_DISPLAYFORMATION, 
		p_default, 		TRUE, 
		p_ui, 			TYPE_SINGLECHEKBOX, IDC_DISPLAYFORMATION, 
		p_end,		
	FormationBhvr::target_color,		_T("targetColor"),TYPE_RGBA, P_RESET_DEFAULT, IDS_TARGETCLR, 
		p_default, 		Point3(0.0,0.0,0.5),
		p_ui, 			TYPE_COLORSWATCH, IDC_TARGETCLR,
		p_end,
	FormationBhvr::display_target,		_T("displayTarget"),	TYPE_BOOL, P_RESET_DEFAULT, IDS_DISPLAYTARGET, 
		p_default, 		TRUE, 
		p_ui, 			TYPE_SINGLECHEKBOX, IDC_TARGETDSPLY, 
		p_end,
	FormationBhvr::target_scale,		_T("targetScale"),	TYPE_FLOAT, P_RESET_DEFAULT, IDS_TARGETSCL, 
		p_default, 		5.0,	
		p_range, 		0.001f, 100000.0f, 
		p_ui, 			TYPE_SPINNER, EDITTYPE_POS_FLOAT, IDC_TARGSCALE, IDC_TARGSCALESPIN, 0.1f, 
		p_end,

	FormationBhvr::force_color,		_T("forceColor"),TYPE_RGBA, P_RESET_DEFAULT, IDS_FORCECLR, 
		p_default, 		Point3(0.0,1.0,1.0),
		p_ui, 			TYPE_COLORSWATCH, IDC_FORCECLR,
Beispiel #20
0
static inline Matrix3 Transpose(const Matrix3& m)
{
    return Matrix3(m.GetColumn3(0), m.GetColumn3(1), m.GetColumn3(2), Point3(0,0,0));
}
Beispiel #21
0
Mesh::Mesh() {
    position = Point3(0,0,0);
}
Beispiel #22
0
u32* texture_buffer_ui;
u32  texture_offset_ui;
u32 textureW_ui = 0;
u32 textureH_ui = 0;


s32 projMatrix_id = -1;
s32 modelViewMatrix_id = -1;
s32 vertexPosition_id = -1;
s32 vertexNormal_id = -1;
s32 vertexTexcoord_id = -1;
s32 textureUnit_id = -1;
s32 scanline_id = -1;

Point3 eye_pos = Point3(0.0f, 0.0f, -10.0f);
Point3 eye_dir = Point3(0.0f, 0.0f, 1.0f);
Vector3 up_vec = Vector3(0.0f,1.0f,0.0f);

void *vp_ucode = NULL;
rsxVertexProgram *vpo = (rsxVertexProgram*)arcade_shader_vpo;

void *fp_ucode = NULL;
rsxFragmentProgram *fpo = (rsxFragmentProgram*)arcade_shader_fpo;

static Matrix4 P;
static SMeshBuffer* quad = NULL;
static SMeshBuffer* quad_ui = NULL;
static Matrix4 modelMatrixBase;
static Matrix4 modelMatrix;
static Matrix4 modelMatrixUi;
Beispiel #23
0
	if (mesh->numTVerts > 0) {
		TVFace* tvf = &mesh->tvFace[faceNum];
		tverts[0] = mesh->tVerts[tvf->getTVert(0)];
		tverts[1] = mesh->tVerts[tvf->getTVert(1)];
		tverts[2] = mesh->tVerts[tvf->getTVert(2)];

		uvw = baryCoord.x*tverts[0] +
				baryCoord.y*tverts[1] +
				baryCoord.z*tverts[2];
	}

	return uvw;
}

static Point3 basic_tva[3] = { Point3(0.0,0.0,0.0),Point3(1.0,0.0,0.0),Point3(1.0,1.0,0.0)};
static Point3 basic_tvb[3] = { Point3(1.0,1.0,0.0),Point3(0.0,1.0,0.0),Point3(0.0,0.0,0.0)};
static int nextpt[3] = {1,2,0};
static int prevpt[3] = {2,0,1};

void MakeFaceUV(Face *f, UVVert *tv)
{
	int na,nhid,i;
	Point3 *basetv;
	/* make the invisible edge be 2->0 */
	nhid = 2;
	if (!(f->flags&EDGE_A))  nhid=0; 
	else if (!(f->flags&EDGE_B)) nhid = 1;
	else if (!(f->flags&EDGE_C)) nhid = 2;
	na = 2-nhid;
	basetv = (f->v[prevpt[nhid]]<f->v[nhid]) ? basic_tva : basic_tvb;
Beispiel #24
0
void GameAsset::common_init() {
  bbox = shared_ptr<BoundingBox>(new BoundingBox(Point3(0,0,0), 1.0, 1.0, 1.0)); // unit cube
}
Beispiel #25
0
//***************************************************************************
// Calculate ambient or diffuse color at each vertex.
// Pass in TRUE as the "diffuse" parameter to calculate the diffuse color.
// If FALSE is passed in, ambient color is calculated.
//***************************************************************************
BOOL calcMixedVertexColors(INode* node, TimeValue t, int lightModel, ColorTab& vxColTab, EvalColProgressCallback* fn)
{
	ObjectState ostate;
	BOOL deleteTri;
	Mesh* mesh;
	SContext sc;
	DefaultLight dl1, dl2;
	MtlBaseLib mtls;
	Matrix3 tm;

	sc.SetNodeAndTime(node, t);
	tm = sc.tmAfterWSM;

	TriObject* tri = GetTriObjectFromNode(node, t, deleteTri);

	// We will only work on GeomObjects
	if (!tri) {
		return FALSE;
	}

	// Get the mesh from the object
	mesh = &tri->GetMesh();
	if (!mesh) {
		return FALSE;
	}

	// If the node doesn't have a material attached,
	// we create a dummy material.
	Mtl* mtl = node->GetMtl();
	if (!mtl) {
		mtl = new DumMtl(Color(node->GetWireColor()));
	}

	mesh->buildRenderNormals();

	vxColTab.ZeroCount();
	vxColTab.Shrink();

	sc.SetMesh(mesh);
	sc.CalcBoundObj();

	// Add the material to the list
	mtls.AddMtl(mtl);

	// Setup ambient light
	if (lightModel == LIGHT_AMBIENT) {
		sc.SetAmbientLight(Color(1.0f, 1.0f, 1.0f));
	}
	else {
		sc.SetAmbientLight(Color(0.0f, 0.0f, 0.0f));
	}

	// If we're using the real lights, we need to find them first
	if (lightModel == LIGHT_SCENELIGHT) {
		AddSceneLights(&sc, &mtls);

		// Add default lights if there are no lights in the scene
		if (sc.lightTab.Count() == 0) {
			dl1.ls.intens = 1.0f;
			dl1.ls.color = Color(0.8f, 0.8f, 0.8f);
			dl1.ls.type = OMNI_LGT;
			dl1.tm = TransMatrix(1000.0f * Point3(-900.0f, -1000.0f, 1500.0f));

			dl2.ls.intens = 1.0f;
			dl2.ls.color = Color(0.8f, 0.8f, 0.8f);
			dl2.ls.type = OMNI_LGT;
			dl2.tm = TransMatrix(-1000.0f * Point3(-900.0f, -1000.0f, 1500.0f));

			sc.AddLight(new LightInfo(&dl1));
			sc.AddLight(new LightInfo(&dl2));
		}

		sc.SetAmbientLight(GetCOREInterface()->GetAmbient(t, FOREVER));
	}

	sc.UpdateLights();
	// Update material
	mtl->Update(t, FOREVER);
	
	int numVerts = mesh->numVerts;
	for (unsigned int v = 0; v < (unsigned)numVerts; v++) {

		if (fn) {
			if (fn->progress(float(v)/float(numVerts))) {
				if (deleteTri) {
					delete tri;
				}

				mtls.Empty();

				if (mtl->ClassID() == DUMMTL_CLASS_ID) {
					delete mtl;
				}

				// What to return here is up for discussion.
				// 1) We are aborting so FALSE might be in order.
				// 2) We have calculated some colors. Let's use what we've got so far.
				return TRUE;
			}
		}

		// Create a new entry
		Color* vxCol = new Color;
		Point3 tmpCol(0.0f, 0.0f, 0.0f);

		int numShades = 0;
		BitArray faceList;
		faceList.SetSize(mesh->numFaces, 0);

		// Get vertex normal
		// We also pass in a BitArray that will be filled in with
		// to inform us to which faces this vertex belongs.
		// We could do this manually, but we need to do it to get
		// the vertex normal anyway so this is done to speed things
		// up a bit.
		Point3 vxNormal = interpVertexNormal(mesh, tm, v, faceList);
		Point3 viewDir = -vxNormal;
		Point3 viewPoint = tm*mesh->verts[v] + 5.0f*vxNormal;
		Point3 lightPos = viewPoint;
		Point3 viewTarget = tm*mesh->verts[v];

		// We now have a viewpoint and a view target.
		// Now we just have to shade this point on the mesh in order
		// to get it's color.
		// Note: 
		// Since materials are assigned on Face basis we need to render each
		// vertex as many times as it has connecting faces.
		// the colors collected are mixed to get the resulting
		// color at each vertex.
		
		for (int nf = 0; nf < faceList.GetSize(); nf++) {
			if (faceList[nf]) {
				// render vertex for this face.
				sc.SetViewPoint(viewPoint);
				sc.SetTargetPoint(viewTarget);
				sc.SetViewDir(viewDir);
				sc.SetFaceNum(nf);
				Face* f = &mesh->faces[nf];
				sc.SetMtlNum(f->getMatID());
				sc.CalcNormals();

				// Setup the barycentric coordinate
				if (mesh->faces[nf].v[0] == v)
					sc.SetBaryCoord(Point3(1.0f, 0.0f, 0.0f));
				else if (mesh->faces[nf].v[1] == v)
					sc.SetBaryCoord(Point3(0.0f, 1.0f, 0.0f));
				else if (mesh->faces[nf].v[2] == v)
					sc.SetBaryCoord(Point3(0.0f, 0.0f, 1.0f));

				// Use diffuse color instead of ambient
				// The only difference is that we create a special light
				// located at the viewpoint and we set the ambient light to black.
				if (lightModel == LIGHT_DIFFUSE) {
					dl1.ls.intens = 1.0f;
					dl1.ls.color = Color(0.8f, 0.8f, 0.8f);
					dl1.ls.type = OMNI_LGT;
					dl1.tm = TransMatrix(lightPos);

					sc.ClearLights();
					sc.AddLight(new LightInfo(&dl1));
					sc.UpdateLights();
				}


				// Shade the vertex
				mtl->Shade(sc);

				tmpCol.x += sc.out.c.r;
				tmpCol.y += sc.out.c.g;
				tmpCol.z += sc.out.c.b;
				numShades++;
			}
		}

		// The color mixes. We just add the colors together and 
		// then divide with as many colors as we added.
		if (numShades > 0) {
			tmpCol = tmpCol / (float)numShades;
		}

		
		vxCol->r = tmpCol.x;
		vxCol->g = tmpCol.y;
		vxCol->b = tmpCol.z;

		
		vxCol->ClampMinMax();

		
		// Append the Color to the table. If the array needs
		// to be realloc'ed, allocate extra space for 100 points.
		vxColTab.Append(1, &vxCol, 100);
	}

	// Some objects gives us a temporary mesh that we need to delete afterwards.
	if (deleteTri) {
		delete tri;
	}


	mtls.Empty();

	if (mtl->ClassID() == DUMMTL_CLASS_ID) {
		delete mtl;
	}

	return TRUE;
}
Beispiel #26
0
void ForceObject::BuildMesh(TimeValue t)
{   ivalid = FOREVER;
    float l1,l2,l3,l4,r1,r2,r3,length;
    pblock->GetValue(PB_ICONSIZE,t,length,ivalid);
    int dorange,dofrange=0,norvs,norfs;
    pblock->GetValue(PB_RANGEON,t,dorange,ivalid);
    if (dorange) {
        dorange=73;
        dofrange=72;
    }
    l1=0.0f;
    l2=length/2.0f;
    l3=0.1f*length;
    l4=length;
    r1=length/6.0f;
    r2=r1/2.0f;
    r3=(r1+r2)/2.0f;
    float u,cosu,sinu,r1cosu,r2cosu,r3cosu,r1sinu,r2sinu,r3sinu;
    mesh.setNumVerts((norvs=76)+dorange);
    mesh.setNumFaces((norfs=84)+dofrange);
    int i,i2,i3,i4,i5,i6,i7;
    i2=NUM_SEGS;
    i3=2*NUM_SEGS;
    i4=3*NUM_SEGS;
    i5=4*NUM_SEGS;
    i6=5*NUM_SEGS;
    i7=6*NUM_SEGS;
    for (i=0; i<NUM_SEGS; i++)
    {   u=float(i)/float(NUM_SEGS)*TWOPI;
        cosu=(float)cos(u);
        sinu=(float)sin(u);
        r1cosu=r1*cosu;
        r1sinu=r1*sinu;
        r2cosu=r2*cosu;
        r2sinu=r2*sinu;
        r3cosu=r3*cosu;
        r3sinu=r3*sinu;
        mesh.setVert(i,   Point3(r1cosu,r1sinu,-l4));
        mesh.setVert(i+i2,Point3(r1cosu,r1sinu,-l2));
        mesh.setVert(i+i3,Point3(r2cosu,r2sinu,-l2));
        mesh.setVert(i+i4,Point3(r2cosu,r2sinu,-l3));
        mesh.setVert(i+i5,Point3(r3cosu,r3sinu,-l3));
        mesh.setVert(i+i6,Point3(r3cosu,r3sinu,-l1));
    }
    mesh.setVert(i7  ,Point3(0.0f,0.0f,-l4));
    mesh.setVert(i7+1,Point3(0.0f,0.0f,-l2));
    mesh.setVert(i7+2,Point3(0.0f,0.0f,-l3));
    mesh.setVert(i7+3,Point3(0.0f,0.0f,-l1));
    for (i=0; i<NUM_SEGS; i++)
    {   int v,v2,v3,v4,v5,v6;
        if (i>(NUM_SEGS-2))
        {   v=0;
            v2=i2;
            v3=i3;
            v4=i4;
            v5=i5;
            v6=i6;
        }
        else
        {   v=i+1;
            v2=v+i2;
            v3=v+i3;
            v4=v+i4;
            v5=v+i5;
            v6=v+i6;
        }
        mesh.faces[i].setEdgeVisFlags(1,0,0);
        mesh.faces[i].setSmGroup(0);
        mesh.faces[i].setVerts(i,v,i7);
        int ii2=i+i2;
        mesh.faces[ii2].setEdgeVisFlags(1,0,0);
        mesh.faces[ii2].setSmGroup(0);
        mesh.faces[ii2].setVerts(ii2,v2,i7+1);
        int ii3=i+i3;
        mesh.faces[ii3].setEdgeVisFlags(1,0,0);
        mesh.faces[ii3].setSmGroup(0);
        mesh.faces[ii3].setVerts(ii3,v3,i7+1);
        int ii4=i+i4;
        mesh.faces[ii4].setEdgeVisFlags(1,0,0);
        mesh.faces[ii4].setSmGroup(0);
        mesh.faces[ii4].setVerts(ii4,v4,i7+2);
        int ii5=i+i5;
        mesh.faces[ii5].setEdgeVisFlags(1,0,0);
        mesh.faces[ii5].setSmGroup(0);
        mesh.faces[ii5].setVerts(ii5,v5,i7+2);
        int ii6=i+i6;
        mesh.faces[ii6].setEdgeVisFlags(1,0,0);
        mesh.faces[ii6].setSmGroup(0);
        mesh.faces[ii6].setVerts(ii6,v6,i7+3);
    }
    mesh.faces[72].setEdgeVisFlags(1,0,0);
    mesh.faces[72].setSmGroup(2);
    mesh.faces[72].setVerts(0,12,6);
    mesh.faces[73].setEdgeVisFlags(0,0,1);
    mesh.faces[73].setSmGroup(2);
    mesh.faces[73].setVerts(6,12,18);
    mesh.faces[74].setEdgeVisFlags(1,0,0);
    mesh.faces[74].setSmGroup(2);
    mesh.faces[74].setVerts(3,15,9);
    mesh.faces[75].setEdgeVisFlags(0,0,1);
    mesh.faces[75].setSmGroup(2);
    mesh.faces[75].setVerts(9,15,21);
    mesh.faces[76].setEdgeVisFlags(1,0,0);
    mesh.faces[76].setSmGroup(2);
    mesh.faces[76].setVerts(24,36,30);
    mesh.faces[77].setEdgeVisFlags(0,0,1);
    mesh.faces[77].setSmGroup(2);
    mesh.faces[77].setVerts(30,36,42);
    mesh.faces[78].setEdgeVisFlags(1,0,0);
    mesh.faces[78].setSmGroup(2);
    mesh.faces[78].setVerts(27,39,33);
    mesh.faces[79].setEdgeVisFlags(0,0,1);
    mesh.faces[79].setSmGroup(2);
    mesh.faces[79].setVerts(33,39,45);
    mesh.faces[80].setEdgeVisFlags(1,0,0);
    mesh.faces[80].setSmGroup(2);
    mesh.faces[80].setVerts(48,60,54);
    mesh.faces[81].setEdgeVisFlags(0,0,1);
    mesh.faces[81].setSmGroup(2);
    mesh.faces[81].setVerts(54,60,66);
    mesh.faces[82].setEdgeVisFlags(1,0,0);
    mesh.faces[82].setSmGroup(2);
    mesh.faces[82].setVerts(51,63,57);
    mesh.faces[83].setEdgeVisFlags(0,0,1);
    mesh.faces[83].setSmGroup(2);
    mesh.faces[83].setVerts(57,63,69);
    if (dorange)
    {   int newv;
        pblock->GetValue(PB_RANGEVAL,t,length,ivalid);
        int i;
        for (i=0; i<NUM_SEGS2; i++)
        {   u = float(i)/float(NUM_SEGS2) * TWOPI;
            mesh.setVert(i+norvs, Point3((float)cos(u) * length, (float)sin(u) * length, 0.0f));
        }
        newv=NUM_SEGS2+norvs;
        for (i=0; i<NUM_SEGS2; i++)
        {   u = float(i)/float(NUM_SEGS2) * TWOPI;
            mesh.setVert(i+newv, Point3(0.0f, (float)cos(u) * length, (float)sin(u) * length));
        }
        newv+=NUM_SEGS2;
        for (i=0; i<NUM_SEGS2; i++)
        {   u = float(i)/float(NUM_SEGS2) * TWOPI;
            mesh.setVert(i+newv, Point3((float)cos(u) * length, 0.0f, (float)sin(u) * length));
        }
        newv+=NUM_SEGS2;
        mesh.setVert(newv, Point3(0.0f, 0.0f, 0.0f));
        int vi=norvs;
        for (i=norfs; i<norfs+dofrange; i++)
        {   int i1 = vi+1;
            if ((i1-norvs)%NUM_SEGS2==0) i1 -= NUM_SEGS2;
            mesh.faces[i].setEdgeVisFlags(1,0,0);
            mesh.faces[i].setSmGroup(0);
            mesh.faces[i].setVerts(vi,i1,newv);
            vi++;
        }
    }
    mesh.InvalidateGeomCache();
}
Beispiel #27
0
void ExtrudeMod::BuildPatchFromShape(TimeValue t,ModContext &mc, ObjectState * os, PatchMesh &pmesh) {
	ShapeObject *shape = (ShapeObject *)os->obj;

	float amount;
	int levels,capStart,capEnd,capType;

	pblock->GetValue(PB_AMOUNT,t,amount,FOREVER);
	pblock->GetValue(PB_SEGS,t,levels,FOREVER);
	if (levels<1) levels = 1;
	pblock->GetValue(PB_CAPSTART,t,capStart,FOREVER);
	pblock->GetValue(PB_CAPEND,t,capEnd,FOREVER);
	pblock->GetValue(PB_CAPTYPE,t,capType,FOREVER);

	BOOL texturing;
	pblock->GetValue(PB_MAPPING, TimeValue(0), texturing, FOREVER);
	BOOL genMatIDs;
	pblock->GetValue(PB_GEN_MATIDS, TimeValue(0), genMatIDs, FOREVER);
	BOOL useShapeIDs;
	pblock->GetValue(PB_USE_SHAPEIDS, TimeValue(0), useShapeIDs, FOREVER);
	BOOL smooth;
	pblock->GetValue(PB_SMOOTH, TimeValue(0), smooth, FOREVER);

	LimitValue(amount, -1000000.0f, 1000000.0f);

	// Get the basic dimension stuff
	float zSize = (float)fabs(amount);
	float baseZ = 0.0f;
	if(amount < 0.0f)
		baseZ = amount;

	// If the shape can convert itself to a BezierShape, have it do so!
	BezierShape bShape;
	if(shape->CanMakeBezier())
		shape->MakeBezier(t, bShape);
	else {
		PolyShape pShape;
		shape->MakePolyShape(t, pShape);
		bShape = pShape;	// UGH -- Convert it from a PolyShape -- not good!
		}
	
//DebugPrint(_T("Extrude organizing shape\n"));
	ShapeHierarchy hier;
	bShape.OrganizeCurves(t, &hier);
	// Need to flip the reversed polys...
	bShape.Reverse(hier.reverse);
	// ...and tell the hierarchy they're no longer reversed!
	hier.reverse.ClearAll();

	// Our shapes are now organized for patch-making -- Let's do the sides!
	int polys = bShape.splineCount;
	int poly, knot;
	int levelVerts = 0, levelVecs = 0, levelPatches = 0, nverts = 0, nvecs = 0, npatches = 0;
	int TVlevels = levels + 1, levelTVerts = 0, ntverts = 0, ntpatches = 0;
	BOOL anyClosed = FALSE;
	for(poly = 0; poly < polys; ++poly) {
		Spline3D *spline = bShape.splines[poly];
		if(!spline->KnotCount())
			continue;
		if(spline->Closed())
			anyClosed = TRUE;
		levelVerts += spline->KnotCount();
		levelTVerts += (spline->Segments() + 1);
		levelVecs += (spline->Segments() * 2);
		levelPatches += spline->Segments();
		}
	nverts = levelVerts * (levels + 1);
	npatches = levelPatches * levels;
	nvecs = (levelVecs * (levels + 1)) + levels * levelVerts * 2 + npatches * 4;
	if(texturing) {
		ntverts = levelTVerts * TVlevels;
		ntpatches = npatches;
		}

	pmesh.setNumVerts(nverts);
	pmesh.setNumVecs(nvecs);
	pmesh.setNumPatches(npatches);
	pmesh.setNumTVerts(ntverts);
	pmesh.setNumTVPatches(ntpatches);

	// Create the vertices!
	int vert = 0;
	int level;
	Point3 offset1, offset2;
	for(poly = 0; poly < polys; ++poly) {
		Spline3D *spline = bShape.splines[poly];
		if(!spline->KnotCount())
			continue;
		int knots = spline->KnotCount();
		for(level = 0; level <= levels; ++level) {
			Point3 offset = Point3(0.0f, 0.0f, baseZ + (float)level / (float)levels * zSize);
			if(level == 0)
				offset1 = offset;
			else
			if(level == levels)
				offset2 = offset;
			for(knot = 0; knot < knots; ++knot) {
				Point3 p = spline->GetKnotPoint(knot);
				pmesh.setVert(vert++, p + offset);
				}
			}
		}
	assert(vert == nverts);

    BOOL usePhysUVs = GetUsePhysicalScaleUVs();
	// Maybe create the texture vertices
	if(texturing) {
		int tvert = 0;
		int level;
		for(poly = 0; poly < polys; ++poly) {
			Spline3D *spline = bShape.splines[poly];
			if(!spline->KnotCount())
				continue;
			// Make it a polyline
			PolyLine pline;
			spline->MakePolyLine(pline, 10);
			int knots = spline->KnotCount();
			for(level = 0; level < TVlevels; ++level) {
				float tV = (float)level / (float)(TVlevels - 1);
                float vScale = usePhysUVs ? amount : 1.0f;
				int lverts = pline.numPts;
				int tp = 0;
				int texPts = spline->Segments() + 1;
				float cumLen = 0.0f;
				float totLen = pline.CurveLength();
                float uScale = usePhysUVs ? totLen : 1.0f;
				Point3 prevPt = pline.pts[0].p;
				int plix = 0;
				while(tp < texPts) {
					Point3 &pt = pline[plix].p;
					cumLen += Length(pt - prevPt);
					prevPt = pt;
					if(pline[plix].flags & POLYPT_KNOT) {
						float tU;
						if(tp == (texPts - 1))
							tU = 1.0f;
						else
							tU = cumLen / totLen;
						pmesh.setTVert(tvert++, UVVert(uScale*tU, vScale*tV, 0.0f));
						tp++;
						}
					plix = (plix + 1) % pline.numPts;
					}
				}
			}
		assert(tvert == ntverts);
		}

	// Create the vectors!
	int seg;
	int vec = 0;
	for(poly = 0; poly < polys; ++poly) {
		Spline3D *spline = bShape.splines[poly];
		if(!spline->KnotCount())
			continue;
		int segs = spline->Segments();
		int knots = spline->KnotCount();
		// First, the vectors on each level
		for(level = 0; level <= levels; ++level) {
			Point3 offset = Point3(0.0f, 0.0f, baseZ + (float)level / (float)levels * zSize);
			for(seg = 0; seg < segs; ++seg) {
				int seg2 = (seg + 1) % knots;
				if(spline->GetLineType(seg) == LTYPE_CURVE) {
					Point3 p = spline->GetOutVec(seg);
					pmesh.setVec(vec++, p + offset);
					p = spline->GetInVec(seg2);
					pmesh.setVec(vec++, p + offset);
					}
				else {
					Point3 p = spline->InterpBezier3D(seg, 0.333333f);
					pmesh.setVec(vec++, p + offset);
					p = spline->InterpBezier3D(seg, 0.666666f);
					pmesh.setVec(vec++, p + offset);
					}
				}
			}
		// Now, the vectors between the levels
		int baseVec = vec;
		for(level = 0; level < levels; ++level) {
			Point3 offsetA = Point3(0.0f, 0.0f, baseZ + (float)level / (float)levels * zSize);
			Point3 offsetB = Point3(0.0f, 0.0f, baseZ + (float)(level + 1) / (float)levels * zSize);
			Point3 offset1 = offsetA + (offsetB - offsetA) * 0.333333333f;
			Point3 offset2 = offsetA + (offsetB - offsetA) * 0.666666666f;
			for(knot = 0; knot < knots; ++knot) {
				Point3 p = spline->GetKnotPoint(knot);
				pmesh.setVec(vec++, p + offset1);
				pmesh.setVec(vec++, p + offset2);
				}
			}
		}

	// Create the patches!
	int np = 0;
	int baseVert = 0;
	int baseVec = 0;
	for(poly = 0; poly < polys; ++poly) {
		Spline3D *spline = bShape.splines[poly];
		if(!spline->KnotCount())
			continue;
		int knots = spline->KnotCount();
		int segs = spline->Segments();
		int baseVec1 = baseVec;	// Base vector index for this level
		int baseVec2 = baseVec + segs * 2 * (levels + 1);	// Base vector index for between levels
		for(level = 0; level < levels; ++level) {
			int sm = 0;
			BOOL firstSmooth = (spline->GetLineType(0) == LTYPE_CURVE && spline->GetLineType(segs-1) == LTYPE_CURVE && (spline->GetKnotType(0) == KTYPE_AUTO || spline->GetKnotType(0) == KTYPE_BEZIER)) ? TRUE : FALSE;
			for(seg = 0; seg < segs; ++seg, vec += 4) {
				int prevseg = (seg + segs - 1) % segs;
				int seg2 = (seg + 1) % knots;
				int a,b,c,d,ab,ba,bc,cb,cd,dc,da,ad;
				MtlID mtl = useShapeIDs ? spline->GetMatID(seg) : 2;
				a = baseVert + seg;
				b = baseVert + seg2;
				c = b + knots;
				d = a + knots;
				ab = baseVec1 + seg * 2;
				ba = ab + 1;
				bc = baseVec2 + seg2 * 2;
				cb = bc + 1;
				cd = ba + (segs * 2);
				dc = ab + (segs * 2);
				da = baseVec2 + seg * 2 + 1;
				ad = da - 1;
//DebugPrint(_T("Making patch %d: %d (%d %d) %d (%d %d) %d (%d %d) %d (%d %d)\n"),np, a, ab, ba, b, bc, cb, c, cd, dc, d, da, ad);
				// If the vertex is not smooth, go to the next group!
				if(seg > 0 && !(spline->GetLineType(prevseg) == LTYPE_CURVE && spline->GetLineType(seg) == LTYPE_CURVE && (spline->GetKnotType(seg) == KTYPE_AUTO || spline->GetKnotType(seg) == KTYPE_BEZIER))) {
					sm++;
					if(sm > 2)
						sm = 1;
					}
				DWORD smoothGroup = 1 << sm;
				if(seg == segs - 1 && firstSmooth) {
					smoothGroup |= 1;
					}
				pmesh.MakeQuadPatch(np, a, ab, ba, b, bc, cb, c, cd, dc, d, da, ad, vec, vec+1, vec+2, vec+3, smooth ? smoothGroup : 0);
				pmesh.setPatchMtlIndex(np++, genMatIDs ? mtl : 0);
				}
			baseVert += knots;
			baseVec1 += (segs * 2);
			baseVec2 += (knots * 2);
			}
		baseVert += knots;
		baseVec += (segs * 2 * (levels + 1) + knots * 2 * levels);
		}
	assert(vec == nvecs);
	assert(np == npatches);

 	// Maybe create the texture patches!
	if(texturing) {
		int ntp = 0;
		int baseTVert = 0;
		for(poly = 0; poly < polys; ++poly) {
			Spline3D *spline = bShape.splines[poly];
			if(!spline->KnotCount())
				continue;
			int pknots = spline->Segments() + 1;
			int pverts = pknots * TVlevels;
			int segs = spline->Segments();
			for(level = 0; level < levels; ++level) {
				for(seg = 0; seg < segs; ++seg) {
					int prevseg = (seg + segs - 1) % segs;
					int seg2 = seg + 1;
					int a,b,c,d;
					a = baseTVert + seg;
					b = baseTVert + seg2;
					c = b + pknots;
					d = a + pknots;
					TVPatch &tp = pmesh.getTVPatch(ntp++);
					tp.setTVerts(a, b, c, d);
					
					}
				baseTVert += pknots;
				}
			baseTVert += pknots;
			}
		assert(ntp == ntpatches);
		}

	// If capping, do it!
	if(anyClosed && (capStart || capEnd)) {
		PatchCapInfo capInfo;
		bShape.MakeCap(t, capInfo);

		// Build information for capping
		PatchCapper capper(bShape);
		if(capStart) {
			vert = 0;
			int baseVec = 0;
			for(poly = 0; poly < polys; ++poly) {
				Spline3D *spline = bShape.splines[poly];
				if(!spline->KnotCount())
					continue;
				PatchCapPoly &capline = capper[poly];
				int lverts = spline->KnotCount();
				for(int v = 0; v < lverts; ++v)
					capline.SetVert(v, vert++);			// Gives this vert's location in the mesh!
				vert += lverts * levels;
				vec = baseVec;
				int lvecs = spline->Segments() * 2;
				for(int v = 0; v < lvecs; ++v)
					capline.SetVec(v, vec++);			// Gives this vec's location in the mesh!
				baseVec += lvecs * (levels + 1) + spline->KnotCount() * levels * 2;
				}
			// Create a work matrix for capping
			Matrix3 mat = TransMatrix(offset1);
			int oldPatches = pmesh.numPatches;
			capper.CapPatchMesh(pmesh, capInfo, TRUE, 16, &mat, genMatIDs ? -1 : 0);
			// If texturing, create the texture patches and vertices
			if(texturing)
				MakePatchCapTexture(pmesh, Inverse(mat), oldPatches, pmesh.numPatches, usePhysUVs);
			}
		if(capEnd) {
			int baseVert = 0;
			int baseVec = 0;
			for(poly = 0; poly < polys; ++poly) {
				Spline3D *spline = bShape.splines[poly];
				if(!spline->KnotCount())
					continue;
				PatchCapPoly &capline = capper[poly];
				int lverts = spline->KnotCount();
				int vert = baseVert + lverts * levels;
				for(int v = 0; v < lverts; ++v)
					capline.SetVert(v, vert++);			// Gives this vert's location in the mesh!
				baseVert += lverts * (levels + 1);
				int lvecs = spline->Segments()*2;
				int vec = baseVec + lvecs * levels;
				for(int v = 0; v < lvecs; ++v)
					capline.SetVec(v, vec++);			// Gives this vec's location in the mesh!
				baseVec += lvecs * (levels + 1) + spline->KnotCount() * levels * 2;
				}
			// Create a work matrix for grid capping
			Matrix3 mat = TransMatrix(offset2);
			int oldPatches = pmesh.numPatches;
			capper.CapPatchMesh(pmesh, capInfo, FALSE, 16, &mat, genMatIDs ? -1 : 0);
			// If texturing, create the texture patches and vertices
			if(texturing)
				MakePatchCapTexture(pmesh, Inverse(mat), oldPatches, pmesh.numPatches, usePhysUVs);
			}
		}

	//watje new mapping
	if(texturing)
		{
		if (ver < 4)
			{
			for (int i = 0; i < pmesh.numPatches; i++)
				pmesh.patches[i].flags |= PATCH_LINEARMAPPING;
			}
		}


	// Ready the patch representation!
	if( !pmesh.buildLinkages() )
   {
      assert(0);
   }
	pmesh.computeInteriors();
	}
Beispiel #28
0
Point3 PtForceField::Force(TimeValue t,const Point3 &pos, const Point3 &vel,int index)
{   Point3 ApplyAt,OutForce,zdir;
    fValid= FOREVER;
    if (!tmValid.InInterval(t))
    {   tmValid=FOREVER;
        tm=node->GetObjectTM(t,&tmValid);
        invtm=Inverse(tm);
    }
    ApplyAt=tm.GetTrans();
    fValid&=tmValid;
    TimeValue t1,t2;

    if (obj == NULL) return Point3(0.0f,0.0f,0.0f);  //667105 watje xrefs can change the base object type through proxies which will cause this to be null or the user can copy a new object type over ours

    obj->pblock->GetValue(PB_ONTIME,t,t1,fValid);
    obj->pblock->GetValue(PB_OFFTIME,t,t2,fValid);
    if ((t>=t1)&&(t<=t2))
    {   float BaseF;
        zdir=tm.GetRow(2);
        obj->pblock->GetValue(PB_STRENGTH,t,BaseF,fValid); //assume N
        int tpf=GetTicksPerFrame();
        //int tpf2=tpf*tpf;
        int tps=TIME_TICKSPERSEC;
        int tps2=tps*tps;
        //int FToTick=(int)((float)tps/(float)GetFrameRate());
        BaseF/=(float)tps2;//convert to kg-m/t2
        BaseF*=100.0f; //convert to kg-cm/t2
        int UnitsVal;
        obj->pblock->GetValue(PB_UNITS,t,UnitsVal,fValid);
        if (UnitsVal!=0) BaseF*=4.4591f; //lbf is this much larger than N=kg-m/s2
        TimeValue tage=t-t1;
        TimeValue Per1,Per2;
        obj->pblock->GetValue(PB_TIMEPER1,t,Per1,fValid);
        obj->pblock->GetValue(PB_TIMEPER2,t,Per2,fValid);
        float scalefactor=1.0f;
        int sintoggle;
        obj->pblock->GetValue(PB_ENABLESINES,t,sintoggle,fValid);
        if (sintoggle)
        {   if (Per1>0)
            {   float phase1,amp1;
                float relage1=(float)tage/(float)Per1;
                obj->pblock->GetValue(PB_PHASPER1,t,phase1,fValid);
                obj->pblock->GetValue(PB_AMP1,t,amp1,fValid);
                scalefactor+=0.01f*amp1*(float)sin(TWOPI*relage1+phase1);
            }
            if (Per2>0)
            {   float phase2,amp2;
                float relage2=(float)tage/(float)Per2;
                obj->pblock->GetValue(PB_PHASPER2,t,phase2,fValid);
                obj->pblock->GetValue(PB_AMP2,t,amp2,fValid);
                scalefactor+=0.01f*amp2*(float)sin(TWOPI*relage2+phase2);
            }
        }
        int feedback;
        obj->pblock->GetValue(PB_FEEDBACKON,t,feedback,fValid);
        float scalefactorg=1.0f;
        if (feedback)
        {   float targetspeed,loopgain;
            obj->pblock->GetValue(PB_TARGETVEL,t,targetspeed,fValid);
            targetspeed/=(float)tpf;
            obj->pblock->GetValue(PB_CONTROLGAIN,t,loopgain,fValid);
            float diffspeed=targetspeed-DotProd(vel,zdir);
            //scalefactorg*=diffspeed*loopgain/(float)tpf;
            scalefactorg*=diffspeed*loopgain/100.0f;
            int revon;
            obj->pblock->GetValue(PB_REVERSIBLE,t,revon,fValid);
            if ((!revon)&&(scalefactorg<0.0f)) scalefactorg=0.0f;
        }
        OutForce=zdir*BaseF*scalefactor*scalefactorg;
        int rangeon;
        obj->pblock->GetValue(PB_RANGEON,t,rangeon,fValid);
        if (rangeon)
        {   float maxrange;
            obj->pblock->GetValue(PB_RANGEVAL,t,maxrange,fValid);
            float distance=Length(ApplyAt-pos);
            if (distance<maxrange)
            {   if (maxrange>FLOAT_EPSILON) OutForce*=(1.0f-distance/maxrange);
                else OutForce=Zero;
            }
            else OutForce=Zero;
        }
    }
    else OutForce=Zero;
    return OutForce*6.25e-03f;
}
Beispiel #29
0
void gridSnap::Snap(Object* pobj, IPoint2 *p, TimeValue t)
{	

	ViewExp *vpt = theman->GetVpt();

	if ( ! vpt || ! vpt->IsAlive() )
	{
		// why are we here
		DbgAssert(!_T("Invalid viewport!"));
		return;
	}

	DbgAssert(vpt != NULL);

	//local copy of the cursor position
	Point2 fp = Point2((float)p->x, (float)p->y);

	BOOL got_one= FALSE;
	//Get point on the consttruction plane 
	Point3 local_cp = vpt->GetPointOnCP(*p);
	Point3 world_snapped;

	Matrix3 tmconst;
	vpt->GetConstructionTM( tmconst );

	// aszabo|nov.01.05|#596889, #613720, #703875 
	// In order to allow snapping to the grid sub-divisions computed based on viewport 
	// the zoom facto, the grid spacing is taken from the viewport.  
	// When the grid is invisible and the zoom factor changes, the viewport returns 
	// the grid spacing computed last time the grid was displayed.
	// When max starts up with hidden grids (via maxstart.max), the viewport's grid 
	// spacing will be zero and in that case we take the grid spacing value specified 
	// in the Grid setting UI.
	float gridSpacing = vpt->GetGridSize();
	if (!(gridSpacing > 0.0f || gridSpacing < 0.0f)) {
		gridSpacing = GetCOREInterface()->GetGridSpacing();
	}


	//Compute all the hit point candidates
	if(	GetActive(INT_SUB))
	{
		float gridZ = 0.f;
#ifdef GAME_VER
		float gridSpacing = GetCOREInterface()->GetGridSpacing();

		SnapInfo si;
		GetCOREInterface()->InitSnapInfo(&si);
		if(si.snapType == SNAP_25D)
			gridZ = GridCoord(local_cp.z,gridSpacing);

		Point3 intsnapped = Point3(GridCoord(local_cp.x,gridSpacing),GridCoord(local_cp.y,gridSpacing),gridZ);
		world_snapped = tmconst * intsnapped;//now in world space
		got_one = TRUE;

		hitmesh = new HitMesh(5);
		hitmesh->setVert(0,tmconst * Point3(intsnapped.x,intsnapped.y - gridSpacing,gridZ));
		hitmesh->setVert(1,tmconst * Point3(intsnapped.x,intsnapped.y + gridSpacing,gridZ));
		hitmesh->setVert(2,tmconst * Point3(intsnapped.x-gridSpacing,intsnapped.y,gridZ));
		hitmesh->setVert(3,tmconst * Point3(intsnapped.x + gridSpacing,intsnapped.y,gridZ));

		//now register a hit with the osnap manager
		//possibly screen for proximity to the foreground
		theman->RecordHit(new OsnapHit(world_snapped, this, INT_SUB, hitmesh));

#else //!GAME_VER
		// aszabo|sep.15.04|#596889|The gridSpacing spacing shouldn't be zero, but if it is, it can lead to infinite loops
		DbgAssert(gridSpacing > 0.0f || gridSpacing < 0.0f);
		if (gridSpacing > 0.0f || gridSpacing < 0.0f)
		{
			// Record all hits that fall in the snap preview area.
			// Grids are infinite, so we can't loop  through their "vertexes".
			// Instead go through only those that are potential snap points, by starting
			// at the closest grid point to the mouse and extending in all directions
			// using "grid size" steps.
			Point3 intsnapped = Point3(GridCoord(local_cp.x,gridSpacing),GridCoord(local_cp.y,gridSpacing),gridZ);
			Point3 curIntsnapped(intsnapped);
			world_snapped = tmconst * intsnapped;

			// set the window transform to identity to guarantee a world-screen transformation.
			if (theman->GetVpt() && theman->GetVpt()->getGW()) {
				theman->GetVpt()->getGW()->setTransform(Matrix3(TRUE));
			}
			// Find all snap points on the right side (positive x) of the intsnapped, including the intsnapped
			while (CheckPotentialHit(&world_snapped,0, fp)) 
			{
				got_one = TRUE;
				RecordNewIntSubHit(world_snapped, tmconst, curIntsnapped, gridSpacing);

				//ktong|Jan.27.2006|#748560|Limit the number of snap points to search only visibly distinct points.
				// If the grid point is too far away to tell it from the next gridpoint, stop searching.
				// No point in enumerating snap points a user can't visibly tell apart.
				// Check after the first snap point (the closest) is registered to at least have one.
				if (TooDistant(theman, world_snapped, gridSpacing)) {
					break;
				}

				// Go down the vertical grid line
				curIntsnapped.y -= gridSpacing;
				FindVerticalIntSubHit(tmconst, curIntsnapped, fp, (-gridSpacing));

				// Go up the vertical grid line
				curIntsnapped.y = intsnapped.y + gridSpacing;
				FindVerticalIntSubHit(tmconst, curIntsnapped, fp, gridSpacing);

				// Go to the right of the original vertival grid line
				curIntsnapped.y = intsnapped.y;
				curIntsnapped.x += gridSpacing;
				world_snapped = tmconst * curIntsnapped;
			} 
			// Find all snap points on the left side (negative x) of the intsnapped
			curIntsnapped.y = intsnapped.y;
			curIntsnapped.x = intsnapped.x - gridSpacing;
			world_snapped = tmconst * curIntsnapped;
			//ktong|Jan.27.2006|#748560|Limit the number of snap points to search only visibly distinct points.
			while (CheckPotentialHit(&world_snapped,0, fp) && !TooDistant(theman, world_snapped, gridSpacing) ) 
			{
				got_one = TRUE;
				RecordNewIntSubHit(world_snapped, tmconst, curIntsnapped, gridSpacing);

				// Go down the vertical grid line
				curIntsnapped.y -= gridSpacing;
				FindVerticalIntSubHit(tmconst, curIntsnapped, fp, (-gridSpacing));

				// Go up the vertical grid line
				curIntsnapped.y = intsnapped.y + gridSpacing;
				FindVerticalIntSubHit(tmconst, curIntsnapped, fp, gridSpacing);

				// Go to the right of the original vertival grid line
				curIntsnapped.y = intsnapped.y;
				curIntsnapped.x -= gridSpacing;
				world_snapped = tmconst * curIntsnapped;
			} 
		}
#endif //GAME_VER
	}


	if(	GetActive(EDGE_SUB) && !got_one)
	{
		BOOL snapx = FALSE;
		float xSnap = GridCoord(local_cp.x,gridSpacing);
		float ySnap = GridCoord(local_cp.y,gridSpacing);
		float xDist = (float)fabs(xSnap - local_cp.x);
		float yDist = (float)fabs(ySnap - local_cp.y);
		Point3 esnapped;

		// Which one is closer?
		if(xDist < yDist)
		{
			snapx = TRUE;
			esnapped = Point3(xSnap,local_cp.y,0.0f);
		}
		else
		{
			esnapped = Point3(local_cp.x,ySnap,0.0f);
		}
		world_snapped = tmconst * esnapped;//now in world space

		if (CheckPotentialHit(&world_snapped,0, fp))
		{
			if(clipgrid(world_snapped, *vpt))
			{
				got_one = TRUE;
				HitMesh* hitmesh = new HitMesh(3);
				if(snapx)
				{
					hitmesh->setVert(0,tmconst * Point3(esnapped.x,esnapped.y - gridSpacing,0.0f));
					hitmesh->setVert(1,tmconst * Point3(esnapped.x,esnapped.y + gridSpacing,0.0f));
				}
				else
				{
					hitmesh->setVert(0,tmconst * Point3(esnapped.x - gridSpacing, esnapped.y,0.0f));
					hitmesh->setVert(1,tmconst * Point3(esnapped.x + gridSpacing, esnapped.y,0.0f));
				}
				theman->RecordHit(new OsnapHit(world_snapped, this, EDGE_SUB, hitmesh));
			}
		}
	}
}
Beispiel #30
0
void MeshExtraData::BuildMeshExtraData( Mesh * mesh, int map_channel )
{
	// UVW Normals setup
	Tab <Point3> norv;

	int i_tf, i_tv;

	SetNumRVerts( mesh->numVerts );
	SetNumFaces( mesh->numFaces );
	SetNumUVerts( mesh->getNumMapVerts(map_channel) );

	faceSel.SetSize( mesh->numFaces );
	faceSel.ClearAll();

	norv.SetCount( mesh->numVerts );

	for (i_tv=0; i_tv<mesh->numVerts; i_tv++) 
	{
		norv[i_tv] = Point3(0,0,0);
	}

	UVVert *mv = mesh->mapVerts( map_channel );
	TVFace *tf = mesh->mapFaces( map_channel );

	for ( i_tf = 0; i_tf < mesh->numFaces; i_tf++ )
	{
		float a0, a1, a2, dp, lenA, lenB;

		Point3 v0 = mv[tf[i_tf].getTVert(0)];
		Point3 v1 = mv[tf[i_tf].getTVert(1)];
		Point3 v2 = mv[tf[i_tf].getTVert(2)];

		lenA = Length( v1 - v0 );
		lenB = Length( v2 - v0 );

		if ( lenA == 0.0f || lenB == 0.0f )
		{
			a0 = 0.0f;
		}
		else
		{
			dp = DotProd((v1-v0)/lenA,(v2-v0)/lenB);
			if (dp>1.0f) dp = 1.0f;
			if (dp<-1.0) dp = -1.0f;
			a0 = acos(dp);
		}

		lenA = Length( v0 - v1 );
		lenB = Length( v2 - v1 );

		if ( lenA == 0.0f || lenB == 0.0f )
		{
			a1 = 0.0f;
		}
		else
		{
			dp = DotProd((v0-v1)/lenA,(v2-v1)/lenB);
			if (dp>1.0f) dp = 1.0f;
			if (dp<-1.0) dp = -1.0f;
			a1 = acos(dp);
		}

		a2 = PI - ( a0 + a1 );

		Point3 vetnorm = (v1-v0)^(v2-v0);
		norv[mesh->faces[i_tf].getVert(0)] += vetnorm * a0;
		norv[mesh->faces[i_tf].getVert(1)] += vetnorm * a1;
		norv[mesh->faces[i_tf].getVert(2)] += vetnorm * a2;
		SetFace(i_tf, IPoint3(	int(mesh->faces[i_tf].getVert(0)),
								int(mesh->faces[i_tf].getVert(1)),
								int(mesh->faces[i_tf].getVert(2))) );
	}

	for (i_tv=0; i_tv<mesh->numVerts; i_tv++) 
	{
		Point3 vnormal = Normalize(norv[i_tv]);
		SetRvert(i_tv,vnormal);
	}	

	// Build Face Selections

	for ( i_tf=0; i_tf<mesh->numFaces; i_tf++ )
	{
		if ( mv[ tf[i_tf].t[0] ] == mv[ tf[i_tf].t[1] ] && mv[ tf[i_tf].t[1] ] == mv[ tf[i_tf].t[2] ] )
			faceSel.Clear(i_tf);
		else 
			faceSel.Set(i_tf);
	}

	if ( faceSel.NumberSet() == 0 ) 
		noneSel = TRUE;
	else
		noneSel = FALSE;
}