void EditPatchMod::ChangeSelVerts(int type) 
{
	ModContextList mcList;		
	INodeTab nodes;
	TimeValue t = ip->GetTime();
	BOOL holdNeeded = FALSE;
	BOOL hadSelected = FALSE;
	
	if (!ip)
		return;
	
	ip->GetModContexts(mcList, nodes);
	ClearPatchDataFlag(mcList, EPD_BEENDONE);
	
	theHold.Begin();
	for (int i = 0; i < mcList.Count(); i++)
	{
		BOOL altered = FALSE;
		EditPatchData *patchData =(EditPatchData*)mcList[i]->localData;
		if (!patchData)
			continue;
		if (patchData->GetFlag(EPD_BEENDONE))
			continue;
		
		// If the mesh isn't yet cache, this will cause it to get cached.
		RPatchMesh *rpatch;
		PatchMesh *patch = patchData->TempData(this)->GetPatch(t, rpatch);
		if (!patch)
			continue;
		
		// If this is the first edit, then the delta arrays will be allocated
		patchData->BeginEdit(t);
		
		// If any bits are set in the selection set, let's DO IT!!
		if (patch->vertSel.NumberSet())
		{
			altered = holdNeeded = TRUE;
			if (theHold.Holding())
				theHold.Put(new PatchRestore(patchData, this, patch, rpatch, "ChangeSelVerts"));
			// Call the vertex type change function
			patch->ChangeVertType(-1, type);
			patchData->UpdateChanges(patch, rpatch, FALSE);
			patchData->TempData(this)->Invalidate(PART_TOPO);
		}
		patchData->SetFlag(EPD_BEENDONE, TRUE);
	}
	
	if (holdNeeded)
		theHold.Accept(GetString(IDS_TH_VERTCHANGE));
	else 
	{
		ip->DisplayTempPrompt(GetString(IDS_TH_NOVERTSSEL), PROMPT_TIME);
		theHold.End();
	}
	
	nodes.DisposeTemporary();
	ClearPatchDataFlag(mcList, EPD_BEENDONE);
	NotifyDependents(FOREVER, PART_TOPO, REFMSG_CHANGE);
	ip->RedrawViews(ip->GetTime(), REDRAW_NORMAL);
}
Exemple #2
0
void EditPatchMod::RecordTopologyTags() 
{
	ModContextList mcList;		
	INodeTab nodes;
	TimeValue t = ip->GetTime();
	ip->GetModContexts(mcList, nodes);
	ClearPatchDataFlag(mcList, EPD_BEENDONE);
	
	for (int i = 0; i < mcList.Count(); i++)
	{
		EditPatchData *patchData =(EditPatchData*)mcList[i]->localData;
		if (!patchData)
			continue;
		if (patchData->GetFlag(EPD_BEENDONE))
			continue;
		
		// If the mesh isn't yet cache, this will cause it to get cached.
		RPatchMesh *rpatch;
		PatchMesh *patch = patchData->TempData(this)->GetPatch(t, rpatch);
		if (!patch)
			continue;
		patch->RecordTopologyTags();
		patchData->SetFlag(EPD_BEENDONE, TRUE);
	}
	
	nodes.DisposeTemporary();
	ClearPatchDataFlag(mcList, EPD_BEENDONE);
}
Exemple #3
0
int TriPatchObject::Display(TimeValue t, INode* inode, ViewExp *vpt, int flags) {

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

	Matrix3 tm;
	GraphicsWindow *gw = vpt->getGW();
	gw->setTransform(inode->GetObjectTM(t));
	UpdatePatchMesh(t);

	if(!MaxSDK::Graphics::IsRetainedModeEnabled())
	{
		if(!(gw->getRndMode() & GW_BOX_MODE)) {
			PrepareMesh(t);
			Mesh& mesh = patch.GetMesh();
			if(mesh.getNumVerts()) {
				mesh.render( gw, inode->Mtls(),
					(flags&USE_DAMAGE_RECT) ? &vpt->GetDammageRect() : NULL, 
					COMP_ALL | (inode->Selected()?COMP_OBJSELECTED:0), inode->NumMtls());	
			}
		}
	}

	patch.render( gw, inode->Mtls(),
		(flags&USE_DAMAGE_RECT) ? &vpt->GetDammageRect() : NULL, 
		COMP_ALL | (inode->Selected()?COMP_OBJSELECTED:0), inode->NumMtls());	
	return(0);
}
    //-----------------------------------------------------------------------
    PatchMeshPtr MeshManager::createBezierPatch(const String& name, const String& groupName, 
            void* controlPointBuffer, VertexDeclaration *declaration, 
            size_t width, size_t height,
            size_t uMaxSubdivisionLevel, size_t vMaxSubdivisionLevel,
            PatchSurface::VisibleSide visibleSide, 
            HardwareBuffer::Usage vbUsage, HardwareBuffer::Usage ibUsage,
            bool vbUseShadow, bool ibUseShadow)
    {
        if (width < 3 || height < 3)
        {
            OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
                "Bezier patch require at least 3x3 control points",
                "MeshManager::createBezierPatch");
        }

        MeshPtr pMesh = getByName(name);
        if (!pMesh.isNull())
        {
            OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, "A mesh called " + name + 
                " already exists!", "MeshManager::createBezierPatch");
        }
        PatchMesh* pm = OGRE_NEW PatchMesh(this, name, getNextHandle(), groupName);
        pm->define(controlPointBuffer, declaration, width, height,
            uMaxSubdivisionLevel, vMaxSubdivisionLevel, visibleSide, vbUsage, ibUsage,
            vbUseShadow, ibUseShadow);
        pm->load();
        ResourcePtr res(pm);
        addImpl(res);

        return res.staticCast<PatchMesh>();
    }
Exemple #5
0
void VWeldMod::ConvertPatchSelection (PatchMesh & mesh) {
	int i;

	switch (mesh.selLevel) {
	case PATCH_OBJECT:
		mesh.vertSel.SetAll ();
		break;
	case PATCH_VERTEX:
		// Don't need to do anything.
		break;
	case PATCH_EDGE:
		mesh.vertSel.ClearAll ();
		for (i=0; i<mesh.getNumEdges(); i++) {		
			if (!mesh.edgeSel[i]) continue;
			mesh.vertSel.Set(mesh.edges[i].v1,TRUE);
			mesh.vertSel.Set(mesh.edges[i].v2,TRUE);
		}
		break;
	case PATCH_PATCH:
		mesh.vertSel.ClearAll ();
		for (i=0; i<mesh.getNumPatches(); i++) {
			if (!mesh.patchSel[i]) continue;
			for (int j=0; j<mesh.patches[i].type; j++) mesh.vertSel.Set (mesh.patches[i].v[j]);
		}
		break;
	}
}
Exemple #6
0
static void MakePatchCapTexture(PatchMesh &pmesh, Matrix3 &itm, int pstart, int pend, BOOL usePhysUVs) {
	if(pstart == pend)
		return;

	// Find out which verts are used by the cap
	BitArray capVerts(pmesh.numVerts);
	capVerts.ClearAll();
	for(int i = pstart; i < pend; ++i) {
		Patch &p = pmesh.patches[i];
		capVerts.Set(p.v[0]);
		capVerts.Set(p.v[1]);
		capVerts.Set(p.v[2]);
		if(p.type == PATCH_QUAD)
			capVerts.Set(p.v[3]);
		}
	// Minmax the verts involved in X/Y axis and total them
	Box3 bounds;
	int numCapVerts = 0;
	int numCapPatches = pend - pstart;
	IntTab capIndexes;
	capIndexes.SetCount(pmesh.numVerts);
	int baseTVert = pmesh.getNumTVerts();
	for(int i = 0; i < pmesh.numVerts; ++i) {
		if(capVerts[i]) {
			capIndexes[i] = baseTVert + numCapVerts++;
			bounds += pmesh.verts[i].p * itm;
			}
		}
	pmesh.setNumTVerts(baseTVert + numCapVerts, TRUE);
	Point3 s;
    if (usePhysUVs)
        s = Point3(1.0f, 1.0f, 0.0f);
    else
        s = Point3(1.0f / bounds.Width().x, 1.0f / bounds.Width().y, 0.0f);
	Point3 t(-bounds.Min().x, -bounds.Min().y, 0.0f);
	// Do the TVerts
	for(int i = 0; i < pmesh.numVerts; ++i) {
		if(capVerts[i])
			pmesh.setTVert(baseTVert++, ((pmesh.verts[i].p * itm) + t) * s);
		}
	// Do the TVPatches
	for(int i = pstart; i < pend; ++i) {
		Patch &p = pmesh.patches[i];
		TVPatch &tp = pmesh.getTVPatch(i);
		if(p.type == PATCH_TRI)
			tp.setTVerts(capIndexes[p.v[0]], capIndexes[p.v[1]], capIndexes[p.v[2]]);
		else
			tp.setTVerts(capIndexes[p.v[0]], capIndexes[p.v[1]], capIndexes[p.v[2]], capIndexes[p.v[3]]);
		}
	}
Exemple #7
0
Mesh* TriPatchObject::GetRenderMesh(TimeValue t, INode *inode, View& view, BOOL& needDelete) {
	UpdatePatchMesh(t);
	TessApprox tess = patch.GetProdTess();
	if (tess.type == TESS_SET) {
		needDelete = FALSE;
		patch.InvalidateMesh(); // force this...
		// temporarlily set the view tess to prod tess
		TessApprox tempTess = patch.GetViewTess();
		patch.SetViewTess(tess);
		PrepareMesh(t);
		patch.SetViewTess(tempTess);
		return &patch.GetMesh();
	} else {
		Mesh *nmesh = new Mesh/*(mesh)*/;
		Matrix3 otm = inode->GetObjectTM(t);

		Box3 bbox;
		GetDeformBBox(t, bbox);
		tess.merge *= Length(bbox.Width())/1000.0f;
		TessApprox disp = patch.GetDispTess();
		disp.merge *= Length(bbox.Width())/1000.0f;

		GetGTessFunction();
		(*psGTessFunc)(&patch, BEZIER_PATCH, &otm, nmesh, &tess, &disp, &view, inode->GetMtl(), FALSE, FALSE);
		if (tess.merge > 0.0f && patch.GetProdTessWeld())
			WeldMesh(nmesh, tess.merge);
		needDelete = TRUE;
		return nmesh;
	}
}
Exemple #8
0
bool TriPatchObject::UpdatePerNodeItems(const MaxSDK::Graphics::UpdateDisplayContext& updateDisplayContext,
										MaxSDK::Graphics::UpdateNodeContext& nodeContext,
										MaxSDK::Graphics::IRenderItemContainer& targetRenderItemContainer)
{
	Mesh& mesh = patch.GetMesh();
	if(mesh.getNumVerts()>0)
	{
		using namespace MaxSDK::Graphics;

		GenerateMeshRenderItemsContext generateRenderItemsContext;
		generateRenderItemsContext.GenerateDefaultContext(updateDisplayContext);
		generateRenderItemsContext.RemoveInvisibleMeshElementDescriptions(nodeContext.GetRenderNode());

		IMeshDisplay2* pMeshDisplay = static_cast<IMeshDisplay2*>(mesh.GetInterface(IMesh_DISPLAY2_INTERFACE_ID));
		if (NULL == pMeshDisplay)
		{
			return false;
		}

		pMeshDisplay->GetRenderItems(generateRenderItemsContext,nodeContext,targetRenderItemContainer);

		return true ;
	}

	return false;
}
Exemple #9
0
int TriPatchObject::Display(TimeValue t, INode* inode, ViewExp *vpt, int flags) {
	Matrix3 tm;
	GraphicsWindow *gw = vpt->getGW();
	gw->setTransform(inode->GetObjectTM(t));
	UpdatePatchMesh(t);
	if(!(gw->getRndMode() & GW_BOX_MODE)) {
		PrepareMesh(t);
		Mesh& mesh = patch.GetMesh();
		if(mesh.getNumVerts()) {
			mesh.render( gw, inode->Mtls(),
				(flags&USE_DAMAGE_RECT) ? &vpt->GetDammageRect() : NULL, 
				COMP_ALL | (inode->Selected()?COMP_OBJSELECTED:0), inode->NumMtls());	
			}
		}
	patch.render( gw, inode->Mtls(),
		(flags&USE_DAMAGE_RECT) ? &vpt->GetDammageRect() : NULL, 
		COMP_ALL | (inode->Selected()?COMP_OBJSELECTED:0), inode->NumMtls());	
	return(0);
	}
Exemple #10
0
// From BaseObject
int TriPatchObject::HitTest(TimeValue t, INode *inode, int type, int crossing, int flags, IPoint2 *p, ViewExp *vpt) {	
	HitRegion hitRegion;
	GraphicsWindow *gw = vpt->getGW();	
	Material *mtl = gw->getMaterial();
   	
	UpdatePatchMesh(t);
	gw->setTransform(inode->GetObjectTM(t));

	MakeHitRegion(hitRegion, type, crossing, 4, p);
	return patch.select( gw, mtl, &hitRegion, flags & HIT_ABORTONHIT );
	}
Exemple #11
0
void TriPatchObject::Snap(TimeValue t, INode* inode, SnapInfo *snap, IPoint2 *p, ViewExp *vpt) {
	if(creating)	// If creating this one, don't try to snap to it!
		return;

	Matrix3 tm = inode->GetObjectTM(t);	
	GraphicsWindow *gw = vpt->getGW();	
   	
	UpdatePatchMesh(t);
	gw->setTransform(tm);

	patch.snap( gw, snap, p, tm );
	}
Exemple #12
0
Object* TriPatchObject::ConvertToType(TimeValue t, Class_ID obtype) {
	if(obtype == patchObjectClassID || obtype == defObjectClassID || obtype == mapObjectClassID) {
		PatchObject *ob;
		UpdatePatchMesh(t);
		ob = new PatchObject();	
		ob->patch = patch;
		ob->SetChannelValidity(TOPO_CHAN_NUM,ObjectValidity(t));
		ob->SetChannelValidity(GEOM_CHAN_NUM,ObjectValidity(t));
		return ob;
		}

	if(obtype == triObjectClassID) {
		TriObject *ob = CreateNewTriObject();
		PrepareMesh(t);
		ob->GetMesh() = patch.GetMesh();
		ob->SetChannelValidity(TOPO_CHAN_NUM,ObjectValidity(t));
		ob->SetChannelValidity(GEOM_CHAN_NUM,ObjectValidity(t));
		return ob;
		}
#ifndef NO_NURBS
	if (obtype==EDITABLE_SURF_CLASS_ID) {
		PatchObject *pob;
		UpdatePatchMesh(t);
		pob = new PatchObject();	
		pob->patch = patch;
		Object *ob = BuildEMObjectFromPatchObject(pob);
		delete pob;
		ob->SetChannelValidity(TOPO_CHAN_NUM, ObjectValidity(t));
		ob->SetChannelValidity(GEOM_CHAN_NUM, ObjectValidity(t));
		return ob;
		}
#endif
	if (Object::CanConvertToType (obtype)) return Object::ConvertToType (t, obtype);

	if (CanConvertPatchObject (obtype)) {
		PatchObject *ob;
		UpdatePatchMesh(t);
		ob = new PatchObject();	
		ob->patch = patch;
		ob->SetChannelValidity(TOPO_CHAN_NUM,ObjectValidity(t));
		ob->SetChannelValidity(GEOM_CHAN_NUM,ObjectValidity(t));
		Object *ret = ob->ConvertToType (t, obtype);
		ob->DeleteThis ();
		return ret;
		}
	return NULL;
	}
Exemple #13
0
// From BaseObject
int TriPatchObject::HitTest(TimeValue t, INode *inode, int type, int crossing, int flags, IPoint2 *p, ViewExp *vpt) {	

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

	HitRegion hitRegion;
	GraphicsWindow *gw = vpt->getGW();	
	Material *mtl = gw->getMaterial();

	UpdatePatchMesh(t);
	gw->setTransform(inode->GetObjectTM(t));

	MakeHitRegion(hitRegion, type, crossing, 4, p);
	return patch.select( gw, mtl, &hitRegion, flags & HIT_ABORTONHIT );
}
Exemple #14
0
bool TriPatchObject::UpdateDisplay(
	const MaxSDK::Graphics::MaxContext& maxContext, 
	const MaxSDK::Graphics::UpdateDisplayContext& displayContext)
{
	// create a mesh to display (leave it in cache)
	PrepareMesh(displayContext.GetDisplayTime());
	Mesh& mesh = patch.GetMesh();
	if(mesh.getNumVerts()>0)
	{
		using namespace MaxSDK::Graphics;

		GenerateMeshRenderItemsContext generateRenderItemsContext;
		generateRenderItemsContext.GenerateDefaultContext(displayContext);

		mesh.GenerateRenderItems(mRenderItemHandles,generateRenderItemsContext);
		return true ;
	}

	return false;
}
Exemple #15
0
void TriPatchObject::Snap(TimeValue t, INode* inode, SnapInfo *snap, IPoint2 *p, ViewExp *vpt) {

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


	if(creating)	// If creating this one, don't try to snap to it!
		return;

	Matrix3 tm = inode->GetObjectTM(t);	
	GraphicsWindow *gw = vpt->getGW();	

	UpdatePatchMesh(t);
	gw->setTransform(tm);

	patch.snap( gw, snap, p, tm );
}
Exemple #16
0
bool TriPatchObject::PrepareDisplay(const MaxSDK::Graphics::UpdateDisplayContext& prepareDisplayContext)
{
	PrepareMesh(prepareDisplayContext.GetDisplayTime());
	Mesh& mesh = patch.GetMesh();
	if(mesh.getNumVerts()>0)
	{
		using namespace MaxSDK::Graphics;

		mRenderItemHandles.ClearAllRenderItems();		
		IMeshDisplay2* pMeshDisplay = static_cast<IMeshDisplay2*>(mesh.GetInterface(IMesh_DISPLAY2_INTERFACE_ID));
		if (NULL == pMeshDisplay)
		{
			return false;
		}

		GenerateMeshRenderItemsContext generateMeshRenderItemsContext;
		generateMeshRenderItemsContext.GenerateDefaultContext(prepareDisplayContext);
		pMeshDisplay->PrepareDisplay(generateMeshRenderItemsContext);

		return true ;
	}

	return false;
}
Exemple #17
0
// Selection set, misc fixup utility function
// This depends on PatchMesh::RecordTopologyTags being called prior to the topo changes
void EditPatchMod::ResolveTopoChanges() 
{
	ModContextList mcList;		
	INodeTab nodes;
	TimeValue t = ip->GetTime();
	ip->GetModContexts(mcList, nodes);
	ClearPatchDataFlag(mcList, EPD_BEENDONE);
	
	for (int i = 0; i < mcList.Count(); i++)
	{
		EditPatchData *patchData =(EditPatchData*)mcList[i]->localData;
		if (!patchData)
			continue;
		if (patchData->GetFlag(EPD_BEENDONE))
			continue;
		
		// If the mesh isn't yet cache, this will cause it to get cached.
		RPatchMesh *rpatch;
		PatchMesh *patch = patchData->TempData(this)->GetPatch(t, rpatch);
		if (!patch)
			continue;
		// First, the vertex selections
		int set;
		for (set = 0; set < patchData->vselSet.Count(); ++set)
		{
			BitArray *oldVS = &patchData->vselSet[set];
			BitArray newVS;
			newVS.SetSize(patch->numVerts);
			for (int vert = 0; vert < patch->numVerts; ++vert)
			{
				// Get the knot's previous location, then copy that selection into the new set
				int tag = patch->verts[vert].aux1;
				if (tag >= 0)
					newVS.Set(vert, (*oldVS)[tag]);
				else
					newVS.Clear(vert);
			}
			if (theHold.Holding())
				theHold.Put(new ChangeNamedSetRestore(&patchData->vselSet, set, oldVS));
			patchData->vselSet[set] = newVS;
		}
		// Now the edge selections
		for (set = 0; set < patchData->eselSet.Count(); ++set)
		{
			BitArray *oldES = &patchData->eselSet[set];
			BitArray newES;
			newES.SetSize(patch->numEdges);
			for (int edge = 0; edge < patch->numEdges; ++edge)
			{
				// Get the knot's previous location, then copy that selection into the new set
				int tag = patch->edges[edge].aux1;
				if (tag >= 0)
					newES.Set(edge, (*oldES)[tag]);
				else
					newES.Clear(edge);
			}
			if (theHold.Holding())
				theHold.Put(new ChangeNamedSetRestore(&patchData->eselSet, set, oldES));
			patchData->eselSet[set] = newES;
		}
		// Now the patch selections
		for (set = 0; set < patchData->pselSet.Count(); ++set)
		{
			BitArray *oldPS = &patchData->pselSet[set];
			BitArray newPS;
			newPS.SetSize(patch->numPatches);
			for (int p = 0; p < patch->numPatches; ++p)
			{
				// Get the knot's previous location, then copy that selection into the new set
				int tag = patch->patches[p].aux1;
				if (tag >= 0)
					newPS.Set(p, (*oldPS)[tag]);
				else
					newPS.Clear(p);
			}
			if (theHold.Holding())
				theHold.Put(new ChangeNamedSetRestore(&patchData->pselSet, set, oldPS));
			patchData->pselSet[set] = newPS;
		}
		
		// watje 4-16-99
		patch->HookFixTopology();
		
		patchData->SetFlag(EPD_BEENDONE, TRUE);
	}
	
	nodes.DisposeTemporary();
	ClearPatchDataFlag(mcList, EPD_BEENDONE);
}
Exemple #18
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();
	}
void PasteSkinWeights::ModifyObject(TimeValue t, ModContext &mc, ObjectState * os, INode *node) 
{
	//TODO: Add the code for actually modifying the object


	Mesh *mesh = NULL;
	MNMesh *mnmesh = NULL;
	PatchMesh *pmesh = NULL;
		
	TriObject *collapsedtobj = NULL;
	if (os->obj->IsSubClassOf(triObjectClassID))
	{
		TriObject *tobj = (TriObject*)os->obj;
		mesh = &tobj->GetMesh();
	}
	else if (os->obj->IsSubClassOf(polyObjectClassID))
	{
		PolyObject *pobj = (PolyObject*)os->obj;
		mnmesh = &pobj->GetMesh();
	}
	else if (os->obj->IsSubClassOf(patchObjectClassID))
	{
		PatchObject *pobj = (PatchObject*)os->obj;
		pmesh = &pobj->patch;
	}


	if (mnmesh)
	{
		int numMaps = mnmesh->numm;
		mnmesh->SetMapNum(numMaps+1);

		int numGFaces = mnmesh->numf;
		int numGVerts = mnmesh->numv;

		numMaps = boneList.Count()/3+1;
		
		mnmesh->SetMapNum(numMaps);
		for (int i = 0; i < boneList.Count(); i++)
		{	
	
			int mapID = i/3;
			int subID = i%3;

			if (subID==0)	//create our face data
			{
				mnmesh->InitMap(mapID);
				mnmesh->M(mapID)->setNumVerts(numGVerts);
//				mnmesh->setNumMapVerts(mapID,numGVerts);
			}
//			TVFace *tvFace = mnmesh->mapFaces(mapID);
			MNMapFace *uvwFace = mnmesh->M(mapID)->f;
			UVVert *tvVerts = mnmesh->M(mapID)->v;//mnmesh->mapVerts(mapID);
			if (subID==0)	//create our face data
			{
				

				
		//copy our original
			//copy our geo faces to the texture faces
				for (int j = 0; j < numGFaces; j++)
				{
					int deg = mnmesh->f[j].deg;
					uvwFace[j].MakePoly(deg,mnmesh->f[j].vtx);
				}	
				for (int j = 0; j < numGVerts; j++)
				{
					tvVerts[j] = Point3(0.0f,0.0f,0.0f);
				}
			}
			
			for (int j = 0; j < boneList[i]->weights.Count(); j++)
			{
				int vertIndex = boneList[i]->weights[j].vertIndex;
				float vertWeight = boneList[i]->weights[j].vertWeight;
				tvVerts[vertIndex][subID] = vertWeight;
			}
		}

		
	}
	else if (mesh)
	{
		int numMaps = mesh->getNumMaps();

		int numGFaces = mesh->numFaces;
		int numGVerts = mesh->numVerts;

		numMaps = boneList.Count()/3+1;
		
		mesh->setNumMaps(numMaps, FALSE);
		for (int i = 0; i < boneList.Count(); i++)
		{	
	
			int mapID = i/3;
			int subID = i%3;

			if (subID==0)	//create our face data
			{
				mesh->setMapSupport(mapID);
				mesh->setNumMapVerts(mapID,numGVerts);
			}
			TVFace *tvFace = mesh->mapFaces(mapID);
			UVVert *tvVerts = mesh->mapVerts(mapID);
			if (subID==0)	//create our face data
			{
				

				
		//copy our original
			//copy our geo faces to the texture faces
				for (int j = 0; j < numGFaces; j++)
				{
					for (int k = 0; k < 3; k++)
					{
						tvFace[j].t[k] = mesh->faces[j].v[k];
					}
				}	
				for (int j = 0; j < numGVerts; j++)
				{
					tvVerts[j] = Point3(0.0f,0.0f,0.0f);
				}
			}
			
			for (int j = 0; j < boneList[i]->weights.Count(); j++)
			{
				int vertIndex = boneList[i]->weights[j].vertIndex;
				float vertWeight = boneList[i]->weights[j].vertWeight;
				tvVerts[vertIndex][subID] = vertWeight;
			}
				
			

			
		}
	}
	else if (pmesh)
	{
		int numMaps = pmesh->getNumMaps();

		int numGFaces = pmesh->numPatches;
		int numGVerts = pmesh->numVerts+pmesh->numVecs;

		numMaps = boneList.Count()/3+1;
		
		pmesh->setNumMaps(numMaps, FALSE);

		for (int i = 0; i < boneList.Count(); i++)
		{	
	
			int mapID = i/3;
			int subID = i%3;

			if (subID==0)	//create our face data
			{
				pmesh->setMapSupport(mapID);
				pmesh->setNumMapVerts(mapID,numGVerts);
			}

			TVPatch *tvFace = pmesh->tvPatches[mapID];;//TVFace *tvFace = pmesh->mapFaces(mapID);
			PatchTVert *tvVerts = pmesh->mapVerts(mapID);
			if (subID==0)	//create our face data
			{
				

				
		//copy our original
			//copy our geo faces to the texture faces
				for (int j = 0; j < numGFaces; j++)
				{
					int deg = 3;
						if (pmesh->patches[j].type == PATCH_QUAD)
						deg = 4;


					for (int k = 0; k < deg; k++)
					{
						int vindex = pmesh->patches[j].v[k];
						tvFace[j].tv[k] = pmesh->patches[j].v[k];
						tvFace[j].interiors[k] = pmesh->patches[j].interior[k]+pmesh->numVerts;
						tvFace[j].handles[k*2] = pmesh->patches[j].vec[k*2]+pmesh->numVerts;
						tvFace[j].handles[k*2+1] = pmesh->patches[j].vec[k*2+1]+pmesh->numVerts;
					}
				}	
				for (int j = 0; j < numGVerts; j++)
				{
					tvVerts[j] = Point3(0.0f,0.0f,0.0f);
				}
			}
			
			for (int j = 0; j < boneList[i]->weights.Count(); j++)
			{
				int vertIndex = boneList[i]->weights[j].vertIndex;
				float vertWeight = boneList[i]->weights[j].vertWeight;
//DebugPrint(_T("bone %d  vert %d weight %f\n"),i,vertIndex,vertWeight);
				tvVerts[vertIndex].p[subID] = vertWeight;
			}
				
			

			
		}
		
	}


	Interval iv;
	iv = FOREVER;

	os->obj->PointsWereChanged();

	iv &= os->obj->ChannelValidity (t, VERT_COLOR_CHAN_NUM);
	iv &= os->obj->ChannelValidity (t, TEXMAP_CHAN_NUM);
	iv = iv & os->obj->ChannelValidity(t,GEOM_CHAN_NUM);
	iv = iv & os->obj->ChannelValidity(t,TOPO_CHAN_NUM);

	os->obj->UpdateValidity(GEOM_CHAN_NUM,iv);	
	os->obj->UpdateValidity (VERT_COLOR_CHAN_NUM, iv);
	os->obj->UpdateValidity(TEXMAP_CHAN_NUM,iv);

}
Exemple #20
0
void TriPatchObject::GetDeformBBox(TimeValue t, Box3& box, Matrix3 *tm, BOOL useSel )
	{
	UpdatePatchMesh(t);
	patch.GetDeformBBox(box, tm, useSel);
	}
Exemple #21
0
ObjectHandle TriPatchObject::CreateTriObjRep(TimeValue t) {
	TriObject *tri = CreateNewTriObject();
	PrepareMesh(t);	// Turn it into a mesh
	tri->GetMesh() = patch.GetMesh();	// Place it into the TriObject
	return(ObjectHandle(tri));
	}
Exemple #22
0
// From GeomObject
int TriPatchObject::IntersectRay(TimeValue t, Ray& r, float& at, Point3& norm) {
	PrepareMesh(t);	// Turn it into a mesh
	return patch.IntersectRay(r, at, norm);
	}
Exemple #23
0
void TriPatchObject::PrepareMesh(TimeValue t) {
	UpdatePatchMesh(t);
	patch.PrepareMesh();
	}
Exemple #24
0
int EditPatchMod::DoAttach(INode *node, PatchMesh *attPatch, RPatchMesh *rattPatch, bool & canUndo)
{
    ModContextList mcList;
    INodeTab nodes;

    if (!ip)
        return 0;

    ip->GetModContexts(mcList, nodes);

    if (mcList.Count() != 1)
    {
        nodes.DisposeTemporary();
        return 0;
    }

    EditPatchData *patchData =(EditPatchData*)mcList[0]->localData;
    if (!patchData)
    {
        nodes.DisposeTemporary();
        return 0;
    }
    patchData->BeginEdit(ip->GetTime());

    // If the mesh isn't yet cached, this will cause it to get cached.
    RPatchMesh *rpatch;
    PatchMesh *patch = patchData->TempData(this)->GetPatch(ip->GetTime(), rpatch);
    if (!patch)
    {
        nodes.DisposeTemporary();
        return 0;
    }
    patchData->RecordTopologyTags(patch);
    RecordTopologyTags();

    // Transform the shape for attachment:
    // If reorienting, just translate to align pivots
    // Otherwise, transform to match our transform
    Matrix3 attMat(1);
    if (attachReorient)
    {
        Matrix3 thisTM = nodes[0]->GetNodeTM(ip->GetTime());
        Matrix3 thisOTMBWSM = nodes[0]->GetObjTMBeforeWSM(ip->GetTime());
        Matrix3 thisPivTM = thisTM * Inverse(thisOTMBWSM);
        Matrix3 otherTM = node->GetNodeTM(ip->GetTime());
        Matrix3 otherOTMBWSM = node->GetObjTMBeforeWSM(ip->GetTime());
        Matrix3 otherPivTM = otherTM * Inverse(otherOTMBWSM);
        Point3 otherObjOffset = node->GetObjOffsetPos();
        attMat = Inverse(otherPivTM) * thisPivTM;
    }
    else
    {
        attMat = node->GetObjectTM(ip->GetTime()) *
                 Inverse(nodes[0]->GetObjectTM(ip->GetTime()));
    }

    // RB 3-17-96 : Check for mirroring
    AffineParts parts;
    decomp_affine(attMat, &parts);
    if (parts.f < 0.0f)
    {
        int v[8], ct, ct2, j;
        Point3 p[9];

        for (int i = 0; i < attPatch->numPatches; i++)
        {

            // Re-order rpatch
            if (attPatch->patches[i].type == PATCH_QUAD)
            {
                UI_PATCH rpatch=rattPatch->getUIPatch (i);
                int ctU=rpatch.NbTilesU<<1;
                int ctV=rpatch.NbTilesV<<1;
                int nU;
                for (nU=0; nU<ctU; nU++)
                {
                    for (int nV=0; nV<ctV; nV++)
                    {
                        rattPatch->getUIPatch (i).getTileDesc (nU+nV*ctU)=rpatch.getTileDesc (ctU-1-nU+(ctV-1-nV)*ctU);
                    }
                }
                for (nU=0; nU<ctU+1; nU++)
                {
                    for (int nV=0; nV<ctV+1; nV++)
                    {
                        rattPatch->getUIPatch (i).setColor (nU+nV*(ctU+1), rpatch.getColor (ctU-nU+(ctV-nV)*ctU));
                    }
                }
            }

            // Re-order vertices
            ct = attPatch->patches[i].type == PATCH_QUAD ? 4 : 3;
            for (j = 0; j < ct; j++)
            {
                v[j] = attPatch->patches[i].v[j];
            }
            for (j = 0; j < ct; j++)
            {
                attPatch->patches[i].v[j] = v[ct - j - 1];
            }

            // Re-order vecs
            ct  = attPatch->patches[i].type == PATCH_QUAD ? 8 : 6;
            ct2 = attPatch->patches[i].type == PATCH_QUAD ? 5 : 3;
            for (j = 0; j < ct; j++)
            {
                v[j] = attPatch->patches[i].vec[j];
            }
            for (j = 0; j < ct; j++, ct2--)
            {
                if (ct2 < 0)
                    ct2 = ct - 1;
                attPatch->patches[i].vec[j] = v[ct2];
            }

            // Re-order enteriors
            if (attPatch->patches[i].type == PATCH_QUAD)
            {
                ct = 4;
                for (j = 0; j < ct; j++)
                {
                    v[j] = attPatch->patches[i].interior[j];
                }
                for (j = 0; j < ct; j++)
                {
                    attPatch->patches[i].interior[j] = v[ct - j - 1];
                }
            }

            // Re-order aux
            if (attPatch->patches[i].type == PATCH_TRI)
            {
                ct = 9;
                for (j = 0; j < ct; j++)
                {
                    p[j] = attPatch->patches[i].aux[j];
                }
                for (j = 0; j < ct; j++)
                {
                    attPatch->patches[i].aux[j] = p[ct - j - 1];
                }
            }

            // Re-order TV faces if present
            for (int chan = 0; chan < patch->getNumMaps(); ++chan)
            {
                if (attPatch->tvPatches[chan])
                {
                    ct = 4;
                    for (j = 0; j < ct; j++)
                    {
                        v[j] = attPatch->tvPatches[chan][i].tv[j];
                    }
                    for (j = 0; j < ct; j++)
                    {
                        attPatch->tvPatches[chan][i].tv[j] = v[ct - j - 1];
                    }
                }
            }
        }
    }

    int i;
    for (i = 0; i < attPatch->numVerts; ++i)
        attPatch->verts[i].p = attPatch->verts[i].p * attMat;
    for (i = 0; i < attPatch->numVecs; ++i)
        attPatch->vecs[i].p = attPatch->vecs[i].p * attMat;
    attPatch->computeInteriors();

    theHold.Begin();

    // Combine the materials of the two nodes.
    int mat2Offset = 0;
    Mtl *m1 = nodes[0]->GetMtl();
    Mtl *m2 = node->GetMtl();
    bool condenseMe = FALSE;
    if (m1 && m2 &&(m1 != m2))
    {
        if (attachMat == ATTACHMAT_IDTOMAT)
        {
            int ct = 1;
            if (m1->IsMultiMtl())
                ct = m1->NumSubMtls();
            for (int i = 0; i < patch->numPatches; ++i)
            {
                int mtid = patch->getPatchMtlIndex(i);
                if (mtid >= ct)
                    patch->setPatchMtlIndex(i, mtid % ct);
            }
            FitPatchIDsToMaterial(*attPatch, m2);
            if (condenseMat)
                condenseMe = TRUE;
        }
        // the theHold calls here were a vain attempt to make this all undoable.
        // This should be revisited in the future so we don't have to use the SYSSET_CLEAR_UNDO.
        theHold.Suspend();
        if (attachMat == ATTACHMAT_MATTOID)
        {
            m1 = FitMaterialToPatchIDs(*patch, m1);
            m2 = FitMaterialToPatchIDs(*attPatch, m2);
        }

        Mtl *multi = CombineMaterials(m1, m2, mat2Offset);
        if (attachMat == ATTACHMAT_NEITHER)
            mat2Offset = 0;
        theHold.Resume();
        // We can't be in face subobject mode, else we screw up the materials:
        DWORD oldSL = patch->selLevel;
        DWORD roldSL = patch->selLevel;
        patch->selLevel = PATCH_OBJECT;
        rpatch->SetSelLevel (EP_OBJECT);
        nodes[0]->SetMtl(multi);
        patch->selLevel = oldSL;
        rpatch->SetSelLevel (roldSL);
        m1 = multi;
        canUndo = FALSE;	// Absolutely cannot undo material combinations.
    }
    if (!m1 && m2)
    {
        // We can't be in face subobject mode, else we screw up the materials:
        DWORD oldSL = patch->selLevel;
        DWORD roldSL = rpatch->GetSelLevel();
        patch->selLevel = PATCH_OBJECT;
        rpatch->SetSelLevel (EP_OBJECT);
        nodes[0]->SetMtl(m2);
        patch->selLevel = oldSL;
        rpatch->SetSelLevel (roldSL);
        m1 = m2;
    }

    // Start a restore object...
    if (theHold.Holding())
        theHold.Put(new PatchRestore(patchData, this, patch, rpatch, "DoAttach"));

    // Do the attach
    patch->Attach(attPatch, mat2Offset);
    rpatch->Attach(rattPatch, *patch);
    patchData->UpdateChanges(patch, rpatch);
    patchData->TempData(this)->Invalidate(PART_TOPO | PART_GEOM);

    // Get rid of the original node
    ip->DeleteNode(node);

    ResolveTopoChanges();
    theHold.Accept(GetString(IDS_TH_ATTACH));

    if (m1 && condenseMe)
    {
        // Following clears undo stack.
        patch = patchData->TempData(this)->GetPatch(ip->GetTime(), rpatch);
        m1 = CondenseMatAssignments(*patch, m1);
    }

    nodes.DisposeTemporary();
    ClearPatchDataFlag(mcList, EPD_BEENDONE);
    NotifyDependents(FOREVER, PART_TOPO | PART_GEOM, REFMSG_CHANGE);
    ip->RedrawViews(ip->GetTime(), REDRAW_NORMAL);
    return 1;
}
Exemple #25
0
void BuildTorusPatch(
		TimeValue t, PatchMesh &patch, 
		float radius1, float radius2, int genUVs, BOOL usePhysUVs)
	{
	int segs = 8, sides = 4;
	int nverts = segs * sides;
	int nvecs = segs*sides*8;
	int npatches = segs * sides;
	patch.setNumVerts(nverts);
	patch.setNumTVerts(genUVs ? (segs + 1) * (sides + 1) : 0);
	patch.setNumVecs(nvecs);
	patch.setNumPatches(npatches);	
	patch.setNumTVPatches(genUVs ? npatches : 0);
	int ix=0, jx=0, kx=sides*segs*4, i, j;
	float ang1 = 0.0f, delta1 = TWOPI/float(segs);
	float ang2 = 0.0f, delta2 = TWOPI/float(sides);	
	float circleLenIn = CIRCLE_FACT8*(radius1-radius2);
	float circleLenOut = CIRCLE_FACT8*(radius1+radius2);
	float circleLenMid = CIRCLE_FACT4*radius2;
	float circleLen;
	float sinang1, cosang1, sinang2, cosang2, rt, u;
	Point3 p, v;
	DWORD a, b, c, d;

	for (i=0; i<segs; i++) {
		sinang1 = (float)sin(ang1);
		cosang1 = (float)cos(ang1);
		ang2 = 0.0f;
		for (j=0; j<sides; j++) {			
			sinang2 = (float)sin(ang2);
			cosang2 = (float)cos(ang2);
			rt = radius1+radius2*cosang2;
			
			// Vertex
			p.x = rt*cosang1;
			p.y = rt*sinang1;
			p.z = radius2*sinang2;	
			patch.setVert(ix, p);
			
			// Tangents			
			u = (cosang2+1.0f)/2.0f;
			circleLen = u*circleLenOut + (1.0f-u)*circleLenIn;

			v.x = -sinang1*circleLen;
			v.y = cosang1*circleLen;
			v.z = 0.0f;
			patch.setVec(jx++,patch.verts[ix] + v);
			
			v.x = sinang1*circleLen;
			v.y = -cosang1*circleLen;
			v.z = 0.0f;
			patch.setVec(jx++,patch.verts[ix] + v);
			
			v.x = -sinang2*cosang1*circleLenMid;
			v.y = -sinang2*sinang1*circleLenMid;
			v.z = cosang2*circleLenMid;
			patch.setVec(jx++,patch.verts[ix] + v);
			
			v.x = sinang2*cosang1*circleLenMid;
			v.y = sinang2*sinang1*circleLenMid;
			v.z = -cosang2*circleLenMid;
			patch.setVec(jx++,patch.verts[ix] + v);			

			// Build the patch
			a = ((i+1)%segs)*sides + (j+1)%sides;
			b = i*sides + (j+1)%sides;
			c = i*sides + j;			
			d = ((i+1)%segs)*sides + j;
			
			patch.patches[ix].SetType(PATCH_QUAD);
			patch.patches[ix].setVerts(a, b, c, d);
			patch.patches[ix].setVecs(
				Tang(a,1),Tang(b,0),Tang(b,3),Tang(c,2),
				Tang(c,0),Tang(d,1),Tang(d,2),Tang(a,3));
			patch.patches[ix].setInteriors(kx, kx+1, kx+2, kx+3);
			patch.patches[ix].smGroup = 1;

			kx += 4;
			ix++;
			ang2 += delta2;
			}		
		ang1 += delta1;
		}	

	if(genUVs) {
		int tv = 0;
		int tvp = 0;
		float fsegs = (float)segs;
		float fsides = (float)sides;
        float uScale = usePhysUVs ? ((float) 2.0f * PI * radius1) : 1.0f;
        float vScale = usePhysUVs ? ((float) 2.0f * PI * radius2) : 1.0f;
		for (i=0; i<=segs; i++) {
			float u = (float)i / (fsegs-1);
			for (j=0; j<=sides; j++,++tv) {
				float v = (float)j / (fsides-1);
                if (usePhysUVs)
                    patch.setTVert(tv, UVVert(vScale*v, uScale*u, 0.0f));
                else
                    patch.setTVert(tv, UVVert(uScale*(1.0f-u), vScale*v, 0.0f));
				if(j < sides && i < segs)
					patch.getTVPatch(tvp++).setTVerts(tv, tv+1, tv+sides+2, tv+sides+1);
				}		
			}	
		}
			
	if( !patch.buildLinkages() )
   {
      assert(0);
   }
	patch.computeInteriors();
	patch.InvalidateGeomCache();
	}
Exemple #26
0
void TriPatchObject::BuildPatch(TimeValue t,PatchMesh& amesh)
	{
	int nverts = 4;
	int nvecs = 16;
	float l, w;
	int tex;
	
	// Start the validity interval at forever and whittle it down.
	ivalid = FOREVER;
	pblock->GetValue( PB_LENGTH, t, l, ivalid );
	pblock->GetValue( PB_WIDTH, t, w, ivalid );
	pblock->GetValue( PB_TEXTURE, t, tex, ivalid );

	amesh.setNumVerts(nverts);
	amesh.setNumTVerts(tex ? nverts : 0);
	amesh.setNumVecs(nvecs);
	amesh.setNumPatches(2);
	amesh.setNumTVPatches(tex ? 2 : 0);

	Point3 v0 = Point3(-w, -l, 0.0f) / 2.0f;   
	Point3 v1 = v0 + Point3(w, 0.0f, 0.0f);
	Point3 v2 = v0 + Point3(w, l, 0.0f);
	Point3 v3 = v0 + Point3(0.0f, l, 0.0f);

	// Create the vertices.
	amesh.verts[0].flags = PVERT_COPLANAR;
	amesh.verts[1].flags = PVERT_COPLANAR;
	amesh.verts[2].flags = PVERT_COPLANAR;
	amesh.verts[3].flags = PVERT_COPLANAR;
	if(tex) {
		amesh.setTVert(0, UVVert(0,0,0));
		amesh.setTVert(1, UVVert(1,0,0));
		amesh.setTVert(2, UVVert(1,1,0));
		amesh.setTVert(3, UVVert(0,1,0));
		}
	amesh.setVert(0, v0);
	amesh.setVert(1, v1);
	amesh.setVert(2, v2);
	amesh.setVert(3, v3);

	// Create the vectors
	MAKEVEC(0, v0, v1);
	MAKEVEC(2, v1, v2);
	MAKEVEC(4, v2, v3);
	MAKEVEC(6, v3, v0);
	MAKEVEC(8, v3, v1);

	// Create patches.
	amesh.MakeTriPatch(0, 0, 0, 1, 1, 9, 8, 3, 6, 7, 10, 11, 12, 1);
	amesh.MakeTriPatch(1, 1, 2, 3, 2, 4, 5, 3, 8, 9, 13, 14, 15, 1);
	Patch &p1 = amesh.patches[0];
	Patch &p2 = amesh.patches[1];
	if(tex) {
		amesh.getTVPatch(0).setTVerts(0,1,3);
		amesh.getTVPatch(1).setTVerts(1,2,3);
		}

	// Finish up patch internal linkages (and bail out if it fails!)
	assert(amesh.buildLinkages());

	// Calculate the interior bezier points on the PatchMesh's patches
	amesh.computeInteriors();

	amesh.InvalidateGeomCache();

	// Tell the PatchMesh it just got changed
	amesh.InvalidateMesh();
	}
Exemple #27
0
void EditPatchMod::ActivateSubobjSel(int level, XFormModes& modes)
{	
	ModContextList mcList;
	INodeTab nodes;
	int old = selLevel;

	if (!ip)
		return;
	ip->GetModContexts(mcList, nodes);

	selLevel = level;
	// 3-10-99 watje
	if (level != EP_PATCH)
	{
		if (ip->GetCommandMode() == bevelMode)
			ip->SetStdCommandMode(CID_OBJMOVE);
		if (ip->GetCommandMode() == extrudeMode)
			ip->SetStdCommandMode(CID_OBJMOVE);
		if (inBevel)
		{
			ISpinnerControl *spin;
			spin = GetISpinner(GetDlgItem(hOpsPanel, IDC_EP_OUTLINESPINNER));
			if (spin)
			{
				HWND hWnd = spin->GetHwnd();
				SendMessage(hWnd, WM_LBUTTONUP, 0, 0);
				ReleaseISpinner(spin);
			}
			
		}
		if (inExtrude)
		{
			ISpinnerControl *spin;
			spin = GetISpinner(GetDlgItem(hOpsPanel, IDC_EP_EXTRUDESPINNER));
			if (spin)
			{
				HWND hWnd = spin->GetHwnd();
				SendMessage(hWnd, WM_LBUTTONUP, 0, 0);
				ReleaseISpinner(spin);
			}
		}
	}	
	if (level != EP_VERTEX)
	{
		if (ip->GetCommandMode() == bindMode)
			ip->SetStdCommandMode(CID_OBJMOVE);
	}


	switch (level)
	{
	case EP_OBJECT:
		// Not imp.
		break;
		
	case EP_PATCH:
		modes = XFormModes(moveMode, rotMode, nuscaleMode, uscaleMode, squashMode, selectMode);
		break;
		
	case EP_EDGE:
		modes = XFormModes(moveMode, rotMode, nuscaleMode, uscaleMode, squashMode, selectMode);
		break;
		
	case EP_VERTEX:
		
		modes = XFormModes(moveMode, rotMode, nuscaleMode, uscaleMode, squashMode, selectMode);
		break;
		
	case EP_TILE:
		
		modes = XFormModes(NULL, NULL, NULL, NULL, NULL, selectMode);
		break;
	}

	if (selLevel != old)
	{
		SetSubobjectLevel(level);
		
		// Modify the caches to reflect the new sel level.
		for (int i = 0; i < mcList.Count(); i++)
		{
			EditPatchData *patchData =(EditPatchData*)mcList[i]->localData;
			if (!patchData)
				continue;		
			
			if (patchData->tempData && patchData->TempData(this)->PatchCached(ip->GetTime()))
			{		
				RPatchMesh *rpatch;
				PatchMesh *patch = patchData->TempData(this)->GetPatch(ip->GetTime(), rpatch);
				if (patch)
				{
					if (selLevel == EP_VERTEX)
						patch->dispFlags = DISP_VERTS;
					else
						patch->dispFlags = 0;
					if (displayLattice)
						patch->SetDispFlag(DISP_LATTICE);
					patch->SetDispFlag(patchLevelDispFlags[selLevel]);
					patch->selLevel = patchLevel[selLevel];
					rpatch->SetSelLevel (selLevel);
				}
			}
		}		
		
		NotifyDependents(FOREVER, PART_SUBSEL_TYPE | PART_DISPLAY, REFMSG_CHANGE);
		ip->PipeSelLevelChanged();
		// Update selection UI display, named sel
		SelectionChanged();
	}

	nodes.DisposeTemporary();
}
void MeshTopoData::SetCache(PatchMesh &patch, int mapChannel)
{
	FreeCache();
	this->patch = new PatchMesh(patch);
	//build TVMAP and edge data

	
	mFSelPrevious.SetSize(patch.patchSel.GetSize());
	mFSelPrevious = patch.patchSel;
	

	if ( (patch.selLevel==PATCH_PATCH) && (patch.patchSel.NumberSet() == 0) ) 
	{
		TVMaps.SetCountFaces(0);
		TVMaps.v.SetCount(0);
		TVMaps.FreeEdges();
		TVMaps.FreeGeomEdges();
		mVSel.SetSize(0);
		mESel.SetSize(0);
		mFSel.SetSize(0);
		mGESel.SetSize(0);
		mGVSel.SetSize(0);
		return;
	}


	//loop through all maps
	//get channel from mesh
	TVMaps.channel = mapChannel;


	//get from mesh based on cahne
	PatchTVert *tVerts = NULL;
	TVPatch *tvFace = NULL;
	if (!patch.getMapSupport(mapChannel))
	{
		patch.setNumMaps(mapChannel+1);
	}

	tVerts = patch.tVerts[mapChannel];
	tvFace = patch.tvPatches[mapChannel];




	if (patch.selLevel!=PATCH_PATCH ) 
	{
		//copy into our structs
		TVMaps.SetCountFaces(patch.getNumPatches());
		TVMaps.v.SetCount(patch.getNumMapVerts(mapChannel));

		mVSel.SetSize(patch.getNumMapVerts (mapChannel));

		TVMaps.geomPoints.SetCount(patch.getNumVerts()+patch.getNumVecs());

		for (int j=0; j<TVMaps.f.Count(); j++) 
		{
			TVMaps.f[j]->flags = 0;


			int pcount = 3;
			if (patch.patches[j].type == PATCH_QUAD) 
			{
				pcount = 4;
			}

			TVMaps.f[j]->t = new int[pcount];
			TVMaps.f[j]->v = new int[pcount];


			if (tvFace == NULL)
			{
				TVMaps.f[j]->t[0] = 0;
				TVMaps.f[j]->t[1] = 0;
				TVMaps.f[j]->t[2] = 0;
				if (pcount ==4) TVMaps.f[j]->t[3] = 0;
				TVMaps.f[j]->FaceIndex = j;
				TVMaps.f[j]->MatID = patch.getPatchMtlIndex(j);
				TVMaps.f[j]->flags = 0;
				TVMaps.f[j]->count = pcount;

				TVMaps.f[j]->vecs = NULL;
				UVW_TVVectorClass *tempv = NULL;
				//new an instance
				if (!(patch.patches[j].flags & PATCH_AUTO))
					TVMaps.f[j]->flags |= FLAG_INTERIOR;

				if (!(patch.patches[j].flags & PATCH_LINEARMAPPING))
				{
					tempv = new UVW_TVVectorClass();
					TVMaps.f[j]->flags |= FLAG_CURVEDMAPPING;
				}
				TVMaps.f[j]->vecs = tempv;	 

				for (int k = 0; k < pcount; k++)
				{
					int index = patch.patches[j].v[k];
					TVMaps.f[j]->v[k] = index;
					TVMaps.geomPoints[index] = patch.verts[index].p;
					//do handles and interiors
					//check if linear
					if (!(patch.patches[j].flags & PATCH_LINEARMAPPING))
					{
						//do geometric points
						index = patch.patches[j].interior[k];
						TVMaps.f[j]->vecs->vinteriors[k] =patch.getNumVerts()+index;
						index = patch.patches[j].vec[k*2];
						TVMaps.f[j]->vecs->vhandles[k*2] =patch.getNumVerts()+index;
						index = patch.patches[j].vec[k*2+1];
						TVMaps.f[j]->vecs->vhandles[k*2+1] =patch.getNumVerts()+index;
						// do texture points do't need to since they don't exist in this case

						TVMaps.f[j]->vecs->interiors[k] =0;								
						TVMaps.f[j]->vecs->handles[k*2] =0;
						TVMaps.f[j]->vecs->handles[k*2+1] =0;

					}

				}

			}
			else
			{
				TVMaps.f[j]->t[0] = tvFace[j].tv[0];
				TVMaps.f[j]->t[1] = tvFace[j].tv[1];
				TVMaps.f[j]->t[2] = tvFace[j].tv[2];
				if (pcount ==4) TVMaps.f[j]->t[3] = tvFace[j].tv[3];
				TVMaps.f[j]->FaceIndex = j;
				TVMaps.f[j]->MatID = patch.getPatchMtlIndex(j);

				TVMaps.f[j]->flags = 0;
				TVMaps.f[j]->count = pcount;


				TVMaps.f[j]->vecs = NULL;
				UVW_TVVectorClass *tempv = NULL;

				if (!(patch.patches[j].flags & PATCH_AUTO))
					TVMaps.f[j]->flags |= FLAG_INTERIOR;
				//new an instance
				if (!(patch.patches[j].flags & PATCH_LINEARMAPPING))
				{
					BOOL mapLinear = FALSE;		
					for (int tvCount = 0; tvCount < patch.patches[j].type*2; tvCount++)
					{
						if (tvFace[j].handles[tvCount] < 0) mapLinear = TRUE;
					}
					if (!(patch.patches[j].flags & PATCH_AUTO))
					{
						for (int tvCount = 0; tvCount < patch.patches[j].type; tvCount++)
						{
							if (tvFace[j].interiors[tvCount] < 0) mapLinear = TRUE;
						}
					}
					if (!mapLinear)
					{
						tempv = new UVW_TVVectorClass();
						TVMaps.f[j]->flags |= FLAG_CURVEDMAPPING;
					}
				}
				TVMaps.f[j]->vecs = tempv;	 


				if ((patch.selLevel==PATCH_PATCH ) && (patch.patchSel[j] == 0))
					TVMaps.f[j]->flags |= FLAG_DEAD;

				for (int k = 0; k < pcount; k++)
				{
					int index = patch.patches[j].v[k];
					TVMaps.f[j]->v[k] = index;
					TVMaps.geomPoints[index] = patch.verts[index].p;
					//							TVMaps.f[j].pt[k] = patch.verts[index].p;
					//do handles and interiors
					//check if linear
					if (TVMaps.f[j]->flags & FLAG_CURVEDMAPPING)
					{
						//do geometric points
						index = patch.patches[j].interior[k];
						TVMaps.f[j]->vecs->vinteriors[k] =patch.getNumVerts()+index;
						index = patch.patches[j].vec[k*2];
						TVMaps.f[j]->vecs->vhandles[k*2] =patch.getNumVerts()+index;
						index = patch.patches[j].vec[k*2+1];
						TVMaps.f[j]->vecs->vhandles[k*2+1] =patch.getNumVerts()+index;
						// do texture points do't need to since they don't exist in this case
						if (TVMaps.f[j]->flags & FLAG_INTERIOR)
						{
							index = tvFace[j].interiors[k];
							TVMaps.f[j]->vecs->interiors[k] =index;
						}
						index = tvFace[j].handles[k*2];
						TVMaps.f[j]->vecs->handles[k*2] =index;
						index = tvFace[j].handles[k*2+1];
						TVMaps.f[j]->vecs->handles[k*2+1] =index;

					}

				}



			}

		}
		for (int geomvecs =0; geomvecs < patch.getNumVecs(); geomvecs++)
		{
			TVMaps.geomPoints[geomvecs+patch.getNumVerts()] = patch.vecs[geomvecs].p;
		}

		for ( int j=0; j<TVMaps.v.Count(); j++) 
		{
			TVMaps.v[j].SetFlag(0);
			if (tVerts)
				TVMaps.v[j].SetP(tVerts[j]);
			else TVMaps.v[j].SetP(Point3(0.0f,0.0f,0.0f));
			TVMaps.v[j].SetInfluence(0.0f);
			TVMaps.v[j].SetControlID(-1);
		}
		if (tvFace == NULL) BuildInitialMapping(&patch);

		TVMaps.mSystemLockedFlag.SetSize(TVMaps.v.Count());
		TVMaps.mSystemLockedFlag.ClearAll();


	}
	else
	{

		//copy into our structs
		TVMaps.SetCountFaces(patch.getNumPatches());

		TVMaps.v.SetCount(patch.getNumMapVerts (mapChannel));

		mVSel.SetSize(patch.getNumMapVerts (mapChannel));

		TVMaps.geomPoints.SetCount(patch.getNumVerts()+patch.getNumVecs());


		for (int j=0; j<TVMaps.f.Count(); j++) 
		{
			TVMaps.f[j]->flags = 0;

			int pcount = 3;

			if (patch.patches[j].type == PATCH_QUAD) 
			{
				pcount = 4;
			}

			TVMaps.f[j]->t = new int[pcount];
			TVMaps.f[j]->v = new int[pcount];

			if (tvFace == NULL)
			{
				TVMaps.f[j]->t[0] = 0;
				TVMaps.f[j]->t[1] = 0;
				TVMaps.f[j]->t[2] = 0;
				if (pcount == 4) TVMaps.f[j]->t[3] = 0;
				TVMaps.f[j]->FaceIndex = j;
				TVMaps.f[j]->MatID = patch.patches[j].getMatID();
				if (patch.patchSel[j])
					TVMaps.f[j]->flags = 0;
				else TVMaps.f[j]->flags = FLAG_DEAD;
				TVMaps.f[j]->count = pcount;

				TVMaps.f[j]->vecs = NULL;
				UVW_TVVectorClass *tempv = NULL;

				if (!(patch.patches[j].flags & PATCH_AUTO))
					TVMaps.f[j]->flags |= FLAG_INTERIOR;

				//new an instance
				if (!(patch.patches[j].flags & PATCH_LINEARMAPPING))
				{
					tempv = new UVW_TVVectorClass();
					TVMaps.f[j]->flags |= FLAG_CURVEDMAPPING;
				}
				TVMaps.f[j]->vecs = tempv;	 


				for (int k = 0; k < pcount; k++)
				{
					int index = patch.patches[j].v[k];
					TVMaps.f[j]->v[k] = index;
					TVMaps.geomPoints[index] = patch.verts[index].p;
					//							TVMaps.f[j].pt[k] = patch.verts[index].p;
					//check if linear
					if (!(patch.patches[j].flags & PATCH_LINEARMAPPING))
					{
						//do geometric points
						index = patch.patches[j].interior[k];
						TVMaps.f[j]->vecs->vinteriors[k] =patch.getNumVerts()+index;
						index = patch.patches[j].vec[k*2];
						TVMaps.f[j]->vecs->vhandles[k*2] =patch.getNumVerts()+index;
						index = patch.patches[j].vec[k*2+1];
						TVMaps.f[j]->vecs->vhandles[k*2+1] =patch.getNumVerts()+index;
						// do texture points do't need to since they don't exist in this case

						TVMaps.f[j]->vecs->interiors[k] =0;								
						TVMaps.f[j]->vecs->handles[k*2] =0;
						TVMaps.f[j]->vecs->handles[k*2+1] =0;

					}

				}

			}
			else
			{
				TVMaps.f[j]->t[0] = tvFace[j].tv[0];
				TVMaps.f[j]->t[1] = tvFace[j].tv[1];
				TVMaps.f[j]->t[2] = tvFace[j].tv[2];
				if (pcount == 4) TVMaps.f[j]->t[3] = tvFace[j].tv[3];
				TVMaps.f[j]->FaceIndex = j;
				TVMaps.f[j]->MatID = patch.patches[j].getMatID();


				if (patch.patchSel[j])
					TVMaps.f[j]->flags = 0;
				else TVMaps.f[j]->flags = FLAG_DEAD;

				int pcount = 3;
				if (patch.patches[j].type == PATCH_QUAD) 
				{
					pcount = 4;
				}
				TVMaps.f[j]->count = pcount;

				TVMaps.f[j]->vecs = NULL;
				UVW_TVVectorClass *tempv = NULL;
				if (!(patch.patches[j].flags & PATCH_AUTO))
					TVMaps.f[j]->flags |= FLAG_INTERIOR;
				//new an instance
				if (!(patch.patches[j].flags & PATCH_LINEARMAPPING))
				{
					BOOL mapLinear = FALSE;		
					for (int tvCount = 0; tvCount < patch.patches[j].type*2; tvCount++)
					{
						if (tvFace[j].handles[tvCount] < 0) mapLinear = TRUE;
					}
					if (!(patch.patches[j].flags & PATCH_AUTO))
					{
						for (int tvCount = 0; tvCount < patch.patches[j].type; tvCount++)
						{
							if (tvFace[j].interiors[tvCount] < 0) mapLinear = TRUE;
						}
					}
					if (!mapLinear)
					{
						tempv = new UVW_TVVectorClass();
						TVMaps.f[j]->flags |= FLAG_CURVEDMAPPING;
					}
				}
				TVMaps.f[j]->vecs = tempv;	 


				for (int k = 0; k < pcount; k++)
				{
					int index = patch.patches[j].v[k];
					TVMaps.f[j]->v[k] = index;
					TVMaps.geomPoints[index] = patch.verts[index].p;
					//							TVMaps.f[j].pt[k] = patch.verts[index].p;
					//do handles and interiors
					//check if linear
					if (TVMaps.f[j]->flags & FLAG_CURVEDMAPPING)
					{
						//do geometric points
						index = patch.patches[j].interior[k];
						TVMaps.f[j]->vecs->vinteriors[k] =patch.getNumVerts()+index;
						index = patch.patches[j].vec[k*2];
						TVMaps.f[j]->vecs->vhandles[k*2] =patch.getNumVerts()+index;
						index = patch.patches[j].vec[k*2+1];
						TVMaps.f[j]->vecs->vhandles[k*2+1] =patch.getNumVerts()+index;
						// do texture points do't need to since they don't exist in this case
						if (TVMaps.f[j]->flags & FLAG_INTERIOR)
						{
							index = tvFace[j].interiors[k];
							TVMaps.f[j]->vecs->interiors[k] =index;
						}
						index = tvFace[j].handles[k*2];
						TVMaps.f[j]->vecs->handles[k*2] =index;
						index = tvFace[j].handles[k*2+1];
						TVMaps.f[j]->vecs->handles[k*2+1] =index;

					}
				}

			}
		}
		for (int j =0; j < patch.getNumVecs(); j++)
		{
			TVMaps.geomPoints[j+patch.getNumVerts()] = patch.vecs[j].p;
		}



		for (int j=0; j<TVMaps.v.Count(); j++) 
		{
//			TVMaps.v[j].SystemLocked(TRUE);
			if (tVerts)
				TVMaps.v[j].SetP(tVerts[j]);
			else TVMaps.v[j].SetP(Point3(.0f,0.0f,0.0f));
			//check if vertex for this face selected
			TVMaps.v[j].SetInfluence(0.0f);
			TVMaps.v[j].SetControlID(-1);

		}


		if (tvFace == NULL) BuildInitialMapping(&patch);
		TVMaps.mSystemLockedFlag.SetSize(TVMaps.v.Count());
		TVMaps.mSystemLockedFlag.SetAll();

		for (int j=0; j<TVMaps.f.Count(); j++) 
		{
			if (!(TVMaps.f[j]->flags & FLAG_DEAD))
			{
				
				int a;
				a = TVMaps.f[j]->t[0];
				TVMaps.v[a].SetFlag(0);
				TVMaps.mSystemLockedFlag.Set(a,FALSE);
				a = TVMaps.f[j]->t[1];
				TVMaps.v[a].SetFlag(0);
				TVMaps.mSystemLockedFlag.Set(a,FALSE);
				a = TVMaps.f[j]->t[2];
				TVMaps.v[a].SetFlag(0);
				TVMaps.mSystemLockedFlag.Set(a,FALSE);

				if (TVMaps.f[j]->count > 3)
				{
					a = TVMaps.f[j]->t[3];
					TVMaps.v[a].SetFlag(0);
					TVMaps.mSystemLockedFlag.Set(a,FALSE);
				}
				if ( (TVMaps.f[j]->flags & FLAG_CURVEDMAPPING) && (TVMaps.f[j]->vecs))
				{
					for (int m =0; m < TVMaps.f[j]->count; m++) 
					{
						int hid = TVMaps.f[j]->vecs->handles[m*2];
						TVMaps.v[hid].SetFlag(0) ;
						TVMaps.mSystemLockedFlag.Set(hid,FALSE);

						hid = TVMaps.f[j]->vecs->handles[m*2+1];
						TVMaps.v[hid].SetFlag(0) ;
						TVMaps.mSystemLockedFlag.Set(hid,FALSE);
					}
					if (TVMaps.f[j]->flags & FLAG_INTERIOR) 
					{
						for (int m =0; m < TVMaps.f[j]->count; m++) 
						{
							int iid = TVMaps.f[j]->vecs->interiors[m];
							TVMaps.v[iid].SetFlag(0);
							TVMaps.mSystemLockedFlag.Set(iid,FALSE);
						}

					}


				}
			}
		}

	}

}
void MeshTopoData::ApplyMapping(PatchMesh &patch, int mapChannel)
{





	//get from mesh 

	if (!patch.getMapSupport(mapChannel) )
	{
		patch.setNumMaps (mapChannel+1);

	}

	TVPatch *tvFace = patch.tvPatches[mapChannel];


	int tvFaceCount =  patch.numPatches;

	if (patch.selLevel!=PATCH_PATCH) 
	{
		//copy into mesh struct
		if (!tvFace) 
		{
			// Create tvfaces and init to 0
			patch.setNumMapPatches(mapChannel,patch.getNumPatches());
			tvFace = patch.tvPatches[mapChannel];
			for (int k=0; k<patch.getNumPatches(); k++)
			{	
				for (int j=0; j<TVMaps.f[k]->count; j++) 
				{
					tvFace[k].tv[j] = 0;			
					tvFace[k].interiors[j] = 0;			
					tvFace[k].handles[j*2] = 0;			
					tvFace[k].handles[j*2+1] = 0;			
				}
			}
		}
		for (int k=0; k<tvFaceCount; k++) 
		{
			if (k < TVMaps.f.Count())
			{
				tvFace[k].tv[0] = TVMaps.f[k]->t[0];
				tvFace[k].tv[1] = TVMaps.f[k]->t[1];
				tvFace[k].tv[2] = TVMaps.f[k]->t[2];
				if (TVMaps.f[k]->count == 4) tvFace[k].tv[3] = TVMaps.f[k]->t[3];
				if (TVMaps.f[k]->flags & FLAG_CURVEDMAPPING)
				{
					patch.patches[k].flags &= ~PATCH_LINEARMAPPING;
					if (TVMaps.f[k]->vecs)
					{
						for (int m = 0;m < TVMaps.f[k]->count;m++)
						{
							if (TVMaps.f[k]->flags & FLAG_INTERIOR)
							{
								tvFace[k].interiors[m] = TVMaps.f[k]->vecs->interiors[m];			
							}

							tvFace[k].handles[m*2] = TVMaps.f[k]->vecs->handles[m*2];			
							tvFace[k].handles[m*2+1] = TVMaps.f[k]->vecs->handles[m*2+1];			
						}
					}

				}
				else patch.patches[k].flags |= PATCH_LINEARMAPPING;
			}
			else{
				tvFace[k].tv[0] = 0;
				tvFace[k].tv[1] = 0;
				tvFace[k].tv[2] = 0;
				if (TVMaps.f[k]->count == 4) tvFace[k].tv[3] = 0;
				for (int m = 0;m < TVMaps.f[k]->count;m++)
				{
					tvFace[k].interiors[m] = 0;			
					tvFace[k].handles[m*2] = 0;			
					tvFace[k].handles[m*2+1] = 0;			
				}

			}
		}
		//match verts
		patch.setNumMapVerts (mapChannel,TVMaps.v.Count());
		PatchTVert *tVerts = patch.tVerts[mapChannel];
		for (int k=0; k<TVMaps.v.Count(); k++) 
			tVerts[k].p = GetTVVert(k);
	}
	else
	{
		//copy into mesh struct
		if (!tvFace) 
		{
			// Create tvfaces and init to 0
			patch.setNumMapPatches (mapChannel,patch.getNumPatches());
			tvFace = patch.tvPatches[mapChannel];
			for (int k=0; k<patch.getNumPatches(); k++)
			{	
				for (int j=0; j<TVMaps.f[k]->count; j++) 
				{
					tvFace[k].tv[j] = 0;			
					tvFace[k].interiors[j] = 0;			
					tvFace[k].handles[j*2] = 0;			
					tvFace[k].handles[j*2+1] = 0;			

				}
			}
		}
		int offset = patch.getNumMapVerts (mapChannel);

		for (int k=0; k<tvFaceCount; k++) 
		{
			//copy if face is selected
			if (patch.patchSel[k])
			{
				tvFace[k].tv[0] = TVMaps.f[k]->t[0]+offset;
				tvFace[k].tv[1] = TVMaps.f[k]->t[1]+offset;
				tvFace[k].tv[2] = TVMaps.f[k]->t[2]+offset;
				if (TVMaps.f[k]->count == 4) tvFace[k].tv[3] = TVMaps.f[k]->t[3]+offset;
				if (TVMaps.f[k]->flags & FLAG_CURVEDMAPPING)
				{
					patch.patches[k].flags &= ~PATCH_LINEARMAPPING;
					if (TVMaps.f[k]->vecs)
					{
						for (int m = 0;m < TVMaps.f[k]->count;m++)
						{
							if (TVMaps.f[k]->flags & FLAG_INTERIOR)
							{
								tvFace[k].interiors[m] = TVMaps.f[k]->vecs->interiors[m]+offset;			
							}
							tvFace[k].handles[m*2] = TVMaps.f[k]->vecs->handles[m*2]+offset;			
							tvFace[k].handles[m*2+1] = TVMaps.f[k]->vecs->handles[m*2+1]+offset;			
						}
					}

				}
				else patch.patches[k].flags |= PATCH_LINEARMAPPING;
			}
		}
		//match verts
		patch.setNumMapVerts (mapChannel,TVMaps.v.Count()+offset,TRUE);
		PatchTVert *tVerts = patch.tVerts[mapChannel];
		for ( int k=0; k<TVMaps.v.Count(); k++) 
			tVerts[k+offset].p = GetTVVert(k);

	}
	RemoveDeadVerts(&patch,mapChannel);
}
Exemple #30
0
void TriPatchObject::FreeCaches() {
	ivalid.SetEmpty();
	patch.FreeAll();
	}