Exemplo n.º 1
0
void SelLum::select(TimeValue t, CompMap &compMap, Bitmap *bm, RenderGlobalContext *gc)
{
	float fTemp;
	int type;

	mp_srcAlpha = (WORD*)bm->GetAlphaPtr(&type);
	mp_srcMap = (WORD*)bm->GetStoragePtr(&type);
	assert(type == BMM_TRUE_48);

	// if source bitmap has changed since last call
	if ( m_lastBMModifyID != bm->GetModifyID() )
	{
		m_lastBMModifyID = bm->GetModifyID();
		m_selectValid = m_featherValid = m_compValid = false;
		if ( (bm->Width() != m_imageW) || (bm->Height() != m_imageH) )
		{
			m_imageW = bm->Width();
			m_imageH = bm->Height();
			m_imageSz = m_imageW * m_imageH;
			if (m_imageSz > m_mapSz)
			{
				if (mp_radMap)
					delete[] mp_radMap;
				mp_radMap = new float[m_imageSz];
				m_mapSz = m_imageSz;
			}
		}
	}

	if (!m_selectValid)
	{
		mp_blurMgr->getSelValue(prmLumMin, t, fTemp, FOREVER);
		LimitValue(fTemp, 0.0f, 100.0f); // mjm - 9.30.99
		m_min = fTemp*PERCENT2DEC;

		mp_blurMgr->getSelValue(prmLumMax, t, fTemp, FOREVER);
		LimitValue(fTemp, 0.0f, 100.0f); // mjm - 9.30.99
		m_max = fTemp*PERCENT2DEC;

		m_selectValid = doSelect();
	}
	
	if (!m_featherValid)
	{
		mp_blurMgr->getSelValue(prmLumFeathRad, t, fTemp, FOREVER);
		LimitValue(fTemp, 0.0f, 1000.0f); // mjm - 9.30.99
		m_feathRad = (int)floor(max(m_imageW, m_imageH)*(fTemp*PERCENT2DEC));
		m_featherValid = SelLum::doFeather();
	}

	mp_blurMgr->getSelValue(prmLumBrighten, t, fTemp, FOREVER);
	LimitValue(fTemp, 0.0f, 1000.0f); // mjm - 9.30.99
	m_brighten = fTemp*PERCENT2DEC;

	mp_blurMgr->getSelValue(prmLumBlend, t, fTemp, FOREVER);
	LimitValue(fTemp, 0.0f, 100.0f); // mjm - 9.30.99
	m_blend = fTemp*PERCENT2DEC;

	m_compValid = SelLum::doComposite(t, compMap);
}
Exemplo n.º 2
0
void ScubaObject::BuildMesh(TimeValue t)
	{	
	int segs, smooth, hsegs;
	float radius,height,pie1, pie2,r2;
	int doPie, genUVs,con;	

	// Start the validity interval at forever and widdle it down.
    FixHeight(pblock,t,(pmapParam?pmapParam->GetHWnd():NULL),increate);
	ivalid = FOREVER;
	
	pblock->GetValue(PB_RADIUS,t,radius,ivalid);
	pblock->GetValue(PB_CENTERS,t,con,ivalid);
	pblock->GetValue(PB_HEIGHT,t,height,ivalid);
	r2=2.0f*radius;
	if (con) height+=(height<0.0f?-r2:r2);
	pblock->GetValue(PB_SIDES,t,segs,ivalid);
	pblock->GetValue(PB_HSEGS,t,hsegs,ivalid);
	pblock->GetValue(PB_SMOOTHON,t,smooth,ivalid);	
	pblock->GetValue(PB_SLICEFROM,t,pie1,ivalid);
	pblock->GetValue(PB_SLICETO,t,pie2,ivalid);	
	pblock->GetValue(PB_SLICEON,t,doPie,ivalid);	
	pblock->GetValue(PB_GENUVS,t,genUVs,ivalid);	
	LimitValue(radius, MIN_RADIUS, MAX_RADIUS);
	LimitValue(height, MIN_HEIGHT, MAX_HEIGHT);
	LimitValue(hsegs, MIN_SEGMENTS, MAX_SEGMENTS);
	LimitValue(segs, MIN_SIDES, MAX_SIDES);
	LimitValue(smooth, 0, 1);	
				//        sides, smooth, 			  cylrad  
	BuildScubaMesh(mesh, segs, smooth, hsegs, doPie,radius, height, pie1, pie2, genUVs, GetUsePhysicalScaleUVs());
	}
Exemplo n.º 3
0
BOOL HelixObject::ValidForDisplay(TimeValue t) {
	float radius1, radius2;
	pblock->GetValue(PB_RADIUS1, t, radius1, ivalid);
	pblock->GetValue(PB_RADIUS2, t, radius2, ivalid);
	LimitValue( radius1, MIN_RADIUS, MAX_RADIUS );
	LimitValue( radius2, MIN_RADIUS, MAX_RADIUS );
	return (radius1 == 0.0f && radius2 == 0.0f) ? FALSE : TRUE;
	}
Exemplo n.º 4
0
void SinWaveObject::BuildMesh(TimeValue t)
	{		
	int startVert = 1, face = 0, nverts, nfaces, numCircles, numCircleSegs, divs;
	float radius = float(0);
	float dr;
	float a, a2, w, s, d;	

	ivalid = FOREVER;
	pblock->GetValue(PB_AMPLITUDE,t,a,ivalid);
	pblock->GetValue(PB_AMPLITUDE2,t,a2,ivalid);
	pblock->GetValue(PB_WAVELEN,t,w,ivalid);
	pblock->GetValue(PB_PHASE,t,s,ivalid);
	pblock->GetValue(PB_DECAY,t,d,ivalid);
	pblock->GetValue(PB_SEGMENTS,t,numCircleSegs,ivalid);
	pblock->GetValue(PB_CIRCLES,t,numCircles,ivalid);
	pblock->GetValue(PB_DIVISIONS,t,divs,ivalid);
	LimitValue(d,0.0f,float(1.0E30));

	dr     = w/float(divs);
	nverts = numCircles * numCircleSegs + 1;
	nfaces = (numCircles-1) * numCircleSegs * 2;
	mesh.setNumVerts(nverts);
	mesh.setNumFaces(nfaces);

	mesh.setVert( 0, Point3(0,0,0) );
	MakeCircle(t,mesh,0,face,radius, a, a2, w, s, d, numCircleSegs);

	for ( int i = 1; i < numCircles; i++ ) {
		MakeCircle(t,mesh,startVert,face,radius, a, a2, w, s, d, numCircleSegs);
		startVert += numCircleSegs;
		radius += dr;
		}
	
	mesh.InvalidateGeomCache();
	}
Exemplo n.º 5
0
Deformer& LinWaveMod::GetDeformer(
		TimeValue t,ModContext &mc,Matrix3& mat,Matrix3& invmat)
	{
	Interval valid;
	static LinWaveDeformer ld;
	pblock->GetValue(PB_FLEX,t,ld.flex,FOREVER);
	LinWaveObject *obj = (LinWaveObject*)GetWSMObject(t);
	obj->pblock->GetValue(PB_AMPLITUDE,t,ld.amp,FOREVER);
	obj->pblock->GetValue(PB_AMPLITUDE2,t,ld.amp2,FOREVER);
	obj->pblock->GetValue(PB_WAVELEN,t,ld.wave,FOREVER);
	obj->pblock->GetValue(PB_PHASE,t,ld.phase,FOREVER);
	obj->pblock->GetValue(PB_DECAY,t,ld.decay,FOREVER);
	LimitValue(ld.decay,0.0f,float(1.0E30));

	ld.time = t;
	//ld.itm  = nodeRef->GetNodeTM(t,&valid);
	ld.itm  = nodeRef->GetObjectTM(t,&valid);
	ld.tm   = Inverse(ld.itm);
	//ld.dist = mc.box ? mc.box->Width().x : (4.0f*ld.wave);
	//ld.dist = (2.0f*ld.wave); // Use wave length for the WSM version
		
	int numSides, divs;
	obj->pblock->GetValue(PB_CIRCLES,t,numSides,FOREVER);
	obj->pblock->GetValue(PB_DIVISIONS,t,divs,FOREVER);	
	ld.dist = (ld.wave/float(divs)) * 4.0f * float(numSides);

	if (ld.dist == 0.0f) ld.dist = 1.0f;
	return ld;
	}
Exemplo n.º 6
0
void ChCylinderObject::BuildMesh(TimeValue t)
	{	
	int segs, smooth, hsegs, capsegs,fsegs;
	float radius,height,pie1, pie2,fillet;
	int doPie, genUVs;	

	FixFillet(pblock,t,(pmapParam?pmapParam->GetHWnd():NULL),increate);
	// Start the validity interval at forever and widdle it down.
	ivalid = FOREVER;
	
	pblock->GetValue(PB_FSEGS,t,fsegs,ivalid);
	pblock->GetValue(PB_SIDES,t,segs,ivalid);
	pblock->GetValue(PB_HSEGS,t,hsegs,ivalid);
	pblock->GetValue(PB_CSEGS,t,capsegs,ivalid);
	pblock->GetValue(PB_RADIUS,t,radius,ivalid);
	pblock->GetValue(PB_HEIGHT,t,height,ivalid);
	pblock->GetValue(PB_FILLET,t,fillet,ivalid);
	pblock->GetValue(PB_SMOOTHON,t,smooth,ivalid);	
	pblock->GetValue(PB_SLICEFROM,t,pie1,ivalid);
	pblock->GetValue(PB_SLICETO,t,pie2,ivalid);	
	pblock->GetValue(PB_SLICEON,t,doPie,ivalid);	
	pblock->GetValue(PB_GENUVS,t,genUVs,ivalid);	
	LimitValue(radius, MIN_RADIUS, MAX_RADIUS);
	LimitValue(height, MIN_HEIGHT, MAX_HEIGHT);
	LimitValue(fsegs, MIN_SEGMENTS, MAX_SEGMENTS);
	LimitValue(hsegs, MIN_SEGMENTS, MAX_SEGMENTS);
	LimitValue(capsegs, MIN_SEGMENTS, MAX_SEGMENTS);
	LimitValue(segs, MIN_SIDES, MAX_SIDES);
	LimitValue(smooth, 0, 1);	
	
	BuildChCylinderMesh(mesh,
		segs, smooth, hsegs, capsegs, fsegs,doPie,
		radius, fillet, height, pie1, pie2, genUVs);
	}
Exemplo n.º 7
0
float SelImage::getBlend(TimeValue t)
{
	float fTemp;
	mp_blurMgr->getSelValue(prmImageBlend, t, fTemp, FOREVER);
	LimitValue(fTemp, 0.0f, 100.0f); // mjm - 9.30.99
	m_blend = fTemp*PERCENT2DEC;

	return m_blend;
};
Exemplo n.º 8
0
void EllipseObject::BuildShape(TimeValue t, BezierShape& ashape) {

	// Start the validity interval at forever and whittle it down.
	ivalid = FOREVER;
	float length;
	float width;
	pblock->GetValue(PB_LENGTH, t, length, ivalid);
	pblock->GetValue(PB_WIDTH, t, width, ivalid);
	LimitValue( length, MIN_LENGTH, MAX_LENGTH );
	LimitValue( width, MIN_WIDTH, MAX_WIDTH );

	// Delete the existing shape and create a new spline in it
	ashape.NewShape();

	// Get parameters from SimpleSpline and place them in the BezierShape
	int steps;
	BOOL optimize,adaptive;
	ipblock->GetValue(IPB_STEPS, t, steps, ivalid);
	ipblock->GetValue(IPB_OPTIMIZE, t, optimize, ivalid);
	ipblock->GetValue(IPB_ADAPTIVE, t, adaptive, ivalid);
	ashape.steps = adaptive ? -1 : steps;
	ashape.optimize = optimize;

	float radius, xmult, ymult;
	if(length < width) {
		radius = width;
		xmult = 1.0f;
		ymult = length / width;
		}
	else
	if(width < length) {
		radius = length;
		xmult = width / length;
		ymult = 1.0f;
		}
	else {
		radius = length;
		xmult = ymult = 1.0f;
		}
	MakeCircle(ashape, radius / 2.0f, xmult, ymult);
	ashape.UpdateSels();	// Make sure it readies the selection set info
	ashape.InvalidateGeomCache();
	}
Exemplo n.º 9
0
void LinWaveObject::BuildMesh(TimeValue t)
	{		
	int startVert = 1, face = 0, nverts, nfaces, numSides, numSegs, divs;
	float radius = float(0);
	float dx, dy, starty, startx;
	float a, a2, w, s, d, x, y, z, u;	
	int nv=0, nf=0, ix, den;

	ivalid = FOREVER;
	pblock->GetValue(PB_AMPLITUDE,t,a,ivalid);
	pblock->GetValue(PB_AMPLITUDE2,t,a2,ivalid);
	pblock->GetValue(PB_WAVELEN,t,w,ivalid);
	pblock->GetValue(PB_PHASE,t,s,ivalid);
	pblock->GetValue(PB_DECAY,t,d,ivalid);
	pblock->GetValue(PB_SEGMENTS,t,numSegs,ivalid);
	pblock->GetValue(PB_CIRCLES,t,numSides,ivalid);
	pblock->GetValue(PB_DIVISIONS,t,divs,ivalid);	
	LimitValue(d,0.0f,float(1.0E30));
	
	dy     = w/float(divs);
	dx     = dy * 4;
	starty = -float(numSegs)/2.0f * dy;
	startx = -float(numSides)/2.0f * dx;
	nverts = (numSides+1) * (numSegs+1);
	nfaces = (numSides) * numSegs * 2;
	mesh.setNumVerts(nverts);
	mesh.setNumFaces(nfaces);

	
	for (int i=0; i<=numSides; i++) {
		x   = startx + dx * float(i);		
		den = (int)(dx*numSides*0.5f);
		u   = (float)fabs(x/(den?den:0.00001f));		
		u   = u*u;
		//u = smoothstep(0.0f,1.0f,u);
		for (int j=0; j<=numSegs; j++) {
			y = starty + float(j) * dy;
			z = WaveFunc(y, t, a*(1.0f-u)+a2*u, w, s, d);
			mesh.setVert(nv++,Point3(x, y, z));			
			}
		}
		
	for (i=0; i<numSides; i++) {
		ix = i * (numSegs+1);
		for (int j=0; j<numSegs; j++) {
			MakeQuad(&(mesh.faces[nf]), 
				ix+numSegs+1+j, ix+numSegs+2+j, ix+1+j, ix+j, 1);				
			nf += 2;
			}
		}
	
	assert(nv==mesh.numVerts);
	assert(nf==mesh.numFaces);
	mesh.InvalidateGeomCache();
	}
Exemplo n.º 10
0
void PyramidObject::BuildMesh(TimeValue t)
	{	
	int hsegs,wsegs,dsegs;
	float height,width,depth;
	int genUVs;	

	// Start the validity interval at forever and widdle it down.
	ivalid = FOREVER;
	
	pblock->GetValue(PB_HSEGS,t,hsegs,ivalid);
	pblock->GetValue(PB_WSEGS,t,wsegs,ivalid);
	pblock->GetValue(PB_DSEGS,t,dsegs,ivalid);
	pblock->GetValue(PB_HEIGHT,t,height,ivalid);
	pblock->GetValue(PB_WIDTH,t,width,ivalid);
	pblock->GetValue(PB_DEPTH,t,depth,ivalid);
	pblock->GetValue(PB_GENUVS,t,genUVs,ivalid);	
	LimitValue(height, MIN_HEIGHT, MAX_HEIGHT);
	LimitValue(width, MIN_HEIGHT, MAX_HEIGHT);
	LimitValue(depth, MIN_HEIGHT, MAX_HEIGHT);
	LimitValue(hsegs, MIN_SEGMENTS, MAX_SEGMENTS);
	LimitValue(wsegs, MIN_SEGMENTS, MAX_SEGMENTS);
	LimitValue(dsegs, MIN_SEGMENTS, MAX_SEGMENTS);
	
    BOOL usePhysUVs = GetUsePhysicalScaleUVs();
	BuildPyramidMesh(mesh, hsegs, wsegs, dsegs, height, 
		width, depth, genUVs, usePhysUVs);
	}
Exemplo n.º 11
0
void DonutObject::BuildShape(TimeValue t, BezierShape& ashape) {
	// Start the validity interval at forever and whittle it down.
	ivalid = FOREVER;
	float radius1;
	float radius2;

	pblock->GetValue(PB_RADIUS1, t, radius1, ivalid);
	
	if(mPipe)
	{
		float thickness;
		pblock->GetValue(PB_THICKNESS, t, thickness, ivalid);
		radius2 = radius1-thickness;
	}
	else
	{
	pblock->GetValue(PB_RADIUS2, t, radius2, ivalid);
	}
		
	LimitValue( radius1, MIN_RADIUS, MAX_RADIUS );
	LimitValue( radius2, MIN_RADIUS, MAX_RADIUS );

	ashape.NewShape();

	// Get parameters from SimpleSpline and place them in the BezierShape
	int steps;
	BOOL optimize,adaptive;
	ipblock->GetValue(IPB_STEPS, t, steps, ivalid);
	ipblock->GetValue(IPB_OPTIMIZE, t, optimize, ivalid);
	ipblock->GetValue(IPB_ADAPTIVE, t, adaptive, ivalid);
	ashape.steps = adaptive ? -1 : steps;
	ashape.optimize = optimize;

	MakeCircle(ashape,radius1);
	MakeCircle(ashape,radius2);
	ashape.UpdateSels();	// Make sure it readies the selection set info
	ashape.InvalidateGeomCache();
	}
Exemplo n.º 12
0
void HelixObject::ReadyInterpParams(TimeValue t) {
	interpValid = FOREVER;
	pblock->GetValue(PB_RADIUS1,t,radius1,interpValid);
	pblock->GetValue(PB_RADIUS2,t,radius2,interpValid);
	pblock->GetValue(PB_HEIGHT,t,height,interpValid);
	pblock->GetValue(PB_TURNS,t,turns,interpValid);
	pblock->GetValue(PB_BIAS,t,bias,interpValid);
	pblock->GetValue(PB_DIRECTION,t,direction,interpValid);
	LimitValue( radius1, MIN_RADIUS, MAX_RADIUS );
	LimitValue( radius2, MIN_RADIUS, MAX_RADIUS );
	LimitValue( height, MIN_HEIGHT, MAX_HEIGHT );
	LimitValue( turns, MIN_TURNS, MAX_TURNS );
	LimitValue( bias, MIN_BIAS, MAX_BIAS );
	totalRadians = TWOPI * turns * ((direction == DIR_CCW) ? 1.0f : -1.0f);
	deltaRadius = radius2 - radius1;
	float quarterTurns = turns * 4.0f;
	power = 1.0f;
	if(bias > 0.0f)
		power = bias * 9.0f + 1.0f;
	else
	if(bias < 0.0f)
		power = -bias * 9.0f + 1.0f;
	}
Exemplo n.º 13
0
Deformer& SinWaveOMod::GetDeformer(
		TimeValue t,ModContext &mc,Matrix3& mat,Matrix3& invmat)
	{
	Interval valid;
	static SinWaveDeformer sd;	
	pblock->GetValue(PB_AMPLITUDE,t,sd.amp,FOREVER);
	pblock->GetValue(PB_AMPLITUDE2,t,sd.amp2,FOREVER);
	pblock->GetValue(PB_WAVELEN,t,sd.wave,FOREVER);
	pblock->GetValue(PB_PHASE,t,sd.phase,FOREVER);
	pblock->GetValue(PB_DECAY,t,sd.decay,FOREVER);
	LimitValue(sd.decay,0.0f,float(1.0E30));
	sd.time = t;
	sd.itm  = invmat;
	sd.tm   = mat;
	sd.flex = 1.0f;
	return sd;
	}
Exemplo n.º 14
0
void BlurUniform::blur(TimeValue t, CompMap *pCompMap, Bitmap *bm, RenderGlobalContext *gc)
{
	// get source bitmap data
	int type;
	mp_srcAlpha = (WORD*)bm->GetAlphaPtr(&type);
	mp_srcMap = (WORD*)bm->GetStoragePtr(&type);
	assert(type == BMM_TRUE_48);

	// if source bitmap has changed since last call
	if ( m_lastBMModifyID != bm->GetModifyID() )
	{
		m_lastBMModifyID = bm->GetModifyID();
		m_blurValid = false;
		if ( (bm->Width() != m_imageW) || (bm->Height() != m_imageH) )
		{
			m_imageW = bm->Width();
			m_imageH = bm->Height();
			m_imageSz = m_imageW * m_imageH;
		}
	}

	// get ui parameters
	float fTemp;
	mp_blurMgr->getBlurValue(prmUnifPixRad, t, fTemp, FOREVER);
	LimitValue(fTemp, 0.0f, 1000.0f); // mjm - 9.30.99
	m_pixRad = (int)( 0.5*floor( max(m_imageW, m_imageH)*(fTemp*PERCENT2DEC) ) );
	mp_blurMgr->getBlurValue(prmUnifAlpha, t, m_affectAlpha, FOREVER);
	mp_blurMgr->getSelValue(prmGenBrightType, t, m_brightenType, FOREVER);

	// setup buffers
	if (m_imageSz > m_mapSz)
	{
		if (mp_scratchMap)
			delete[] mp_scratchMap;
		mp_scratchMap = new AColor[m_imageSz];

		if (mp_blurCache)
			delete[] mp_blurCache;
		mp_blurCache = new AColor[m_imageSz];

		m_mapSz = m_imageSz;
	}

	m_blurValid = doBlur(pCompMap, mp_srcMap, mp_srcMap, mp_srcAlpha, (m_affectAlpha) ? mp_srcAlpha : NULL);
};
Exemplo n.º 15
0
Deformer& LinWaveOMod::GetDeformer(
		TimeValue t,ModContext &mc,Matrix3& mat,Matrix3& invmat)
	{
	Interval valid;
	static LinWaveDeformer ld;	
	pblock->GetValue(PB_AMPLITUDE,t,ld.amp,FOREVER);
	pblock->GetValue(PB_AMPLITUDE2,t,ld.amp2,FOREVER);
	pblock->GetValue(PB_WAVELEN,t,ld.wave,FOREVER);
	pblock->GetValue(PB_PHASE,t,ld.phase,FOREVER);
	pblock->GetValue(PB_DECAY,t,ld.decay,FOREVER);
	LimitValue(ld.decay,0.0f,float(1.0E30));
	ld.time = t;
	ld.itm  = invmat;
	ld.tm   = mat;
	ld.flex = 1.0f;
	ld.dist = mc.box ? mc.box->Width().x : (4.0f*ld.wave);
	return ld;
	}
Exemplo n.º 16
0
Deformer& SinWaveMod::GetDeformer(
		TimeValue t,ModContext &mc,Matrix3& mat,Matrix3& invmat)
	{
	Interval valid;
	static SinWaveDeformer sd;
	pblock->GetValue(PB_FLEX,t,sd.flex,FOREVER);
	SinWaveObject *obj = (SinWaveObject*)GetWSMObject(t);
	obj->pblock->GetValue(PB_AMPLITUDE,t,sd.amp,FOREVER);
	obj->pblock->GetValue(PB_AMPLITUDE2,t,sd.amp2,FOREVER);
	obj->pblock->GetValue(PB_WAVELEN,t,sd.wave,FOREVER);
	obj->pblock->GetValue(PB_PHASE,t,sd.phase,FOREVER);
	obj->pblock->GetValue(PB_DECAY,t,sd.decay,FOREVER);
	LimitValue(sd.decay,0.0f,float(1.0E30));

	sd.time = t;
	//sd.itm  = nodeRef->GetNodeTM(t,&valid);
	sd.itm  = nodeRef->GetObjectTM(t,&valid);
	sd.tm   = Inverse( sd.itm );
	return sd;
	}
Exemplo n.º 17
0
void PrismObject::BuildMesh(TimeValue t)
	{	
	int hsegs,s1segs,s2segs,s3segs;
	float height,s1len,s2len,s3len;
	int genUVs;	

	if (isdone)
	{  FixSide1(pblock,t,(pmapParam?pmapParam->GetHWnd():NULL));
	   FixSide2(pblock,t,(pmapParam?pmapParam->GetHWnd():NULL));
	   FixSide3(pblock,t,(pmapParam?pmapParam->GetHWnd():NULL));
	}

	// Start the validity interval at forever and widdle it down.
	ivalid = FOREVER;
	
	pblock->GetValue(PB_HSEGS,t,hsegs,ivalid);
	pblock->GetValue(PB_S1SEGS,t,s1segs,ivalid);
	pblock->GetValue(PB_S2SEGS,t,s2segs,ivalid);
	pblock->GetValue(PB_S3SEGS,t,s3segs,ivalid);
	pblock->GetValue(PB_HEIGHT,t,height,ivalid);
	pblock->GetValue(PB_SIDE1,t,s1len,ivalid);
	pblock->GetValue(PB_SIDE2,t,s2len,ivalid);
	pblock->GetValue(PB_SIDE3,t,s3len,ivalid);
	pblock->GetValue(PB_GENUVS,t,genUVs,ivalid);	
	LimitValue(height, MIN_HEIGHT, MAX_HEIGHT);
	LimitValue(s1len, BMIN_HEIGHT, MAX_HEIGHT);
	LimitValue(s2len, BMIN_HEIGHT, MAX_HEIGHT);
	LimitValue(s3len, BMIN_HEIGHT, MAX_HEIGHT);
	LimitValue(hsegs, MIN_SEGMENTS, MAX_SEGMENTS);
	LimitValue(s1segs, MIN_SEGMENTS, MAX_SEGMENTS);
	LimitValue(s2segs, MIN_SEGMENTS, MAX_SEGMENTS);
	LimitValue(s3segs, MIN_SEGMENTS, MAX_SEGMENTS);
	
	BuildPrismMesh(mesh, s1segs, s2segs, s3segs, hsegs, 
		s1len, s2len, s3len, height, genUVs);
	}
Exemplo n.º 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();
	}
Exemplo n.º 19
0
void RectangleObject::BuildShape(TimeValue t, BezierShape& ashape) {

	// Start the validity interval at forever and whittle it down.
	ivalid = FOREVER;
	float length,fillet;
	float width;
	pblock->GetValue(PB_LENGTH, t, length, ivalid);
	pblock->GetValue(PB_WIDTH, t, width, ivalid);
	pblock->GetValue(PB_FILLET, t, fillet, ivalid);
	LimitValue( length, MIN_LENGTH, MAX_LENGTH );
	LimitValue( width, MIN_WIDTH, MAX_WIDTH );
	LimitValue( fillet, MIN_WIDTH, MAX_WIDTH );
	// Delete the existing shape and create a new spline in it
	ashape.NewShape();

	// Get parameters from SimpleSpline and place them in the BezierShape
	int steps;
	BOOL optimize,adaptive;
	ipblock->GetValue(IPB_STEPS, t, steps, ivalid);
	ipblock->GetValue(IPB_OPTIMIZE, t, optimize, ivalid);
	ipblock->GetValue(IPB_ADAPTIVE, t, adaptive, ivalid);
	ashape.steps = adaptive ? -1 : steps;
	ashape.optimize = optimize;

	Spline3D *spline = ashape.NewSpline();

	// Now add all the necessary points
	// We'll add 'em as auto corners initially, have the spline package compute some vectors (because
	// I'm basically lazy and it does a great job, besides) then turn 'em into bezier corners!
	float l2 = length / 2.0f;
	float w2 = width / 2.0f;
	Point3 p = Point3(w2, l2, 0.0f);
	int pts=4;
	if (fillet>0)
	{ pts=8;
	  float cf=fillet*CIRCLE_VECTOR_LENGTH;
	  Point3 wvec=Point3(fillet,0.0f,0.0f),lvec=Point3(0.0f,fillet,0.0f);
	  Point3 cwvec=Point3(cf,0.0f,0.0f),clvec=Point3(0.0f,cf,0.0f);
	  Point3 p3=p-lvec,p2;
	  spline->AddKnot(SplineKnot(KTYPE_BEZIER,LTYPE_CURVE,p3,p3-clvec,p3+clvec));
	  p=p-wvec;
	  spline->AddKnot(SplineKnot(KTYPE_BEZIER,LTYPE_CURVE,p,p+cwvec,p-cwvec));
	  p=Point3(-w2,l2,0.0f);p2=p+wvec;
	  spline->AddKnot(SplineKnot(KTYPE_BEZIER,LTYPE_CURVE,p2,p2+cwvec,p2-cwvec));
	  p=p-lvec;
	  spline->AddKnot(SplineKnot(KTYPE_BEZIER,LTYPE_CURVE,p,p+clvec,p-clvec));
	  p=Point3(-w2,-l2,0.0f);p3=p+lvec;
	  spline->AddKnot(SplineKnot(KTYPE_BEZIER,LTYPE_CURVE,p3,p3+clvec,p3-clvec));
	  p=p+wvec;
	  spline->AddKnot(SplineKnot(KTYPE_BEZIER,LTYPE_CURVE,p,p-cwvec,p+cwvec));
	  p = Point3(w2, -l2, 0.0f);p3=p-wvec;
	  spline->AddKnot(SplineKnot(KTYPE_BEZIER,LTYPE_CURVE,p3,p3-cwvec,p3+cwvec));
	  p=p+lvec;
	  spline->AddKnot(SplineKnot(KTYPE_BEZIER,LTYPE_CURVE,p,p-clvec,p+clvec));
	spline->SetClosed();
	spline->ComputeBezPoints();
	} 
	else
	{spline->AddKnot(SplineKnot(KTYPE_CORNER,LTYPE_CURVE,p,p,p));
	p = Point3(-w2, l2, 0.0f);
	spline->AddKnot(SplineKnot(KTYPE_CORNER,LTYPE_CURVE,p,p,p));
	p = Point3(-w2, -l2, 0.0f);
	spline->AddKnot(SplineKnot(KTYPE_CORNER,LTYPE_CURVE,p,p,p));
	p = Point3(w2, -l2, 0.0f);
	spline->AddKnot(SplineKnot(KTYPE_CORNER,LTYPE_CURVE,p,p,p));
	spline->SetClosed();
	spline->ComputeBezPoints();
	for(int i = 0; i < 4; ++i)
		spline->SetKnotType(i, KTYPE_BEZIER_CORNER);
	}
	spline->SetClosed();
	spline->ComputeBezPoints();
	for(int i = 0; i < pts; ++i)
		spline->SetKnotType(i, KTYPE_BEZIER_CORNER);
	ashape.UpdateSels();	// Make sure it readies the selection set info
	ashape.InvalidateGeomCache();
	}
Exemplo n.º 20
0
void SelMaps::select(TimeValue t, CompMap &compMap, Bitmap *bm, RenderGlobalContext *gc)
{
	int type;

	mp_srcAlpha = (WORD*)bm->GetAlphaPtr(&type);
	mp_srcMap = (WORD*)bm->GetStoragePtr(&type);
	assert(type == BMM_TRUE_48);
	m_shadeContext.globContext = gc;

	// if source bitmap has changed since last call
	if ( m_lastBMModifyID != bm->GetModifyID() )
	{
		m_lastBMModifyID = bm->GetModifyID();
		m_selectValid = m_featherValid = m_compValid = false;
		if ( (bm->Width() != m_imageW) || (bm->Height() != m_imageH) )
		{
			m_imageW = bm->Width();
			m_imageH = bm->Height();
			m_imageSz = m_imageW * m_imageH;
			if (m_imageSz > m_mapSz)
			{
				if (mp_radMap)
					delete[] mp_radMap;
				mp_radMap = new float[m_imageSz];
				m_mapSz = m_imageSz;
			}
		}
	}

	float fTemp;
	if (!m_selectValid)
	{
		m_brightenMap = NULL;
		mp_blurMgr->getSelValue(prmMaskMap, 0, m_brightenMap, FOREVER);
		if (!m_brightenMap)
			return;
		m_shadeContext.scale = 1.0f;
		m_shadeContext.duvw  = Point3(1.0f/float(m_imageW), 1.0f/float(m_imageH), 0.0f);
		m_shadeContext.uvw.z = 0.0f;
		m_shadeContext.filterMaps = TRUE;
		m_brightenMap->Update(t, Interval());
		m_brightenMap->LoadMapFiles(t);

		mp_blurMgr->getSelValue(prmMaskChannel, t, m_channel, FOREVER);
		mp_blurMgr->getSelValue(prmMaskMin, t, fTemp, FOREVER);
		LimitValue(fTemp, 0.0f, 100.0f); // mjm - 9.30.99
		m_min = fTemp*PERCENT2DEC;

		mp_blurMgr->getSelValue(prmMaskMax, t, fTemp, FOREVER);
		LimitValue(fTemp, 0.0f, 100.0f); // mjm - 9.30.99
		m_max = fTemp*PERCENT2DEC;

		m_selectValid = doSelect();
	}

	if (!m_featherValid)
	{
		mp_blurMgr->getSelValue(prmMaskFeathRad, t, fTemp, FOREVER);
		LimitValue(fTemp, 0.0f, 1000.0f); // mjm - 9.30.99
		m_feathRad = (int)floor(max(m_imageW, m_imageH)*(fTemp*PERCENT2DEC));
		m_featherValid = doFeather();
	}

	mp_blurMgr->getSelValue(prmMaskBrighten, t, fTemp, FOREVER);
	LimitValue(fTemp, 0.0f, 1000.0f); // mjm - 9.30.99
	m_brighten = fTemp*PERCENT2DEC;

	mp_blurMgr->getSelValue(prmMaskBlend, t, fTemp, FOREVER);
	LimitValue(fTemp, 0.0f, 100.0f); // mjm - 9.30.99
	m_blend = fTemp*PERCENT2DEC;

	m_compValid = doComposite(t, compMap);
}
Exemplo n.º 21
0
void TorusObject::BuildMesh(TimeValue t)
	{
	Point3 p;
	int ix,na,nb,nc,nd,jx,kx;
	int nf=0,nv=0;
	float delta,ang;
	float delta2,ang2;
	int sides,segs,smooth;
	float radius,radius2, rotation;
	float sinang,cosang, sinang2,cosang2,rt;
	float twist, pie1, pie2, totalPie, startAng = 0.0f;
	int doPie  = TRUE;	
	int genUVs = TRUE;	

	// Start the validity interval at forever and widdle it down.
	ivalid = FOREVER;	
	pblock->GetValue(PB_RADIUS,t,radius,ivalid);
	pblock->GetValue(PB_RADIUS2,t,radius2,ivalid);
	pblock->GetValue(PB_ROTATION,t,rotation,ivalid);
	pblock->GetValue(PB_TWIST,t,twist,ivalid);
	pblock->GetValue(PB_SEGMENTS,t,segs,ivalid);
	pblock->GetValue(PB_SIDES,t,sides,ivalid);
	pblock->GetValue(PB_SMOOTH,t,smooth,ivalid);
	pblock->GetValue(PB_PIESLICE1,t,pie1,ivalid);
	pblock->GetValue(PB_PIESLICE2,t,pie2,ivalid);	
	pblock->GetValue(PB_SLICEON,t,doPie,ivalid);
	pblock->GetValue(PB_GENUVS,t,genUVs,ivalid);
	LimitValue( radius, MIN_RADIUS, MAX_RADIUS );
	LimitValue( radius2, MIN_RADIUS, MAX_RADIUS );
	LimitValue( segs, MIN_SEGMENTS, MAX_SEGMENTS );
	LimitValue( sides, MIN_SIDES, MAX_SIDES );	

    // Convert doPie to a 0 or 1 value since it is used in arithmetic below
    // Controllers can give it non- 0 or 1 values
    doPie = doPie ? 1 : 0;

	// We do the torus backwards from the cylinder
	pie1 = -pie1;
	pie2 = -pie2;

	// Make pie2 < pie1 and pie1-pie2 < TWOPI
	while (pie1 < pie2) pie1 += TWOPI;
	while (pie1 > pie2+TWOPI) pie1 -= TWOPI;
	if (pie1==pie2) totalPie = TWOPI;
	else totalPie = pie1-pie2;	
	
	if (doPie) {
		segs++; //*** O.Z. fix for bug 240436 
		delta    = totalPie/(float)(segs-1);
		startAng = pie2;
	} else {
		delta = (float)2.0*PI/(float)segs;
		}
	
	delta2 = (float)2.0*PI/(float)sides;
	
	if (TestAFlag(A_PLUGIN1)) startAng -= HALFPI;

	int nverts;
	int nfaces;
	if (doPie) {
		nverts = sides*segs + 2;
		nfaces = 2*sides*segs;
	} else {
		nverts = sides*segs;
		nfaces = 2*sides*segs;
		}
	mesh.setNumVerts(nverts);
	mesh.setNumFaces(nfaces);
	mesh.setSmoothFlags(smooth);
	if (genUVs) {
		if (doPie) {
			mesh.setNumTVerts((sides+1)*segs+2);
			mesh.setNumTVFaces(2*sides*segs);
		} else {
			mesh.setNumTVerts((sides+1)*(segs+1));
			mesh.setNumTVFaces(2*sides*segs);
			}
	} else {
		mesh.setNumTVerts(0);
		mesh.setNumTVFaces(0);
		}

	ang = startAng;

	// make verts
	for(ix=0; ix<segs; ix++) {
		sinang = (float)sin(ang);
		cosang = (float)cos(ang);
		ang2 = rotation + twist * float(ix+1)/float(segs);
		for (jx = 0; jx<sides; jx++) {
			sinang2 = (float)sin(ang2);
			cosang2 = (float)cos(ang2);
			rt = radius+radius2*cosang2;
			p.x = rt*cosang;
			p.y = -rt*sinang;
			p.z = radius2*sinang2;	
			mesh.setVert(nv++, p);
			ang2 += delta2;
			}	
		ang += delta;
		}
	
	if (doPie) {
		p.x = radius * (float)cos(startAng);
		p.y = -radius * (float)sin(startAng);
		p.z = 0.0f;
		mesh.setVert(nv++, p);

		ang -= delta;
		p.x = radius * (float)cos(ang);
		p.y = -radius * (float)sin(ang);
		p.z = 0.0f;
		mesh.setVert(nv++, p);
		}
	
	// Make faces

    BOOL usePhysUVs = GetUsePhysicalScaleUVs();
    BitArray startSliceFaces;
    BitArray endSliceFaces;

    if (usePhysUVs) {
        startSliceFaces.SetSize(mesh.numFaces);
        endSliceFaces.SetSize(mesh.numFaces);
    }

	/* Make midsection */
	for(ix=0; ix<segs-doPie; ++ix) {
		jx=ix*sides;
		for (kx=0; kx<sides; ++kx) {
			na = jx+kx;
			nb = (ix==(segs-1))?kx:na+sides;
			nd = (kx==(sides-1))? jx : na+1;
			nc = nb+nd-na;

			DWORD grp = 0;
			if (smooth==SMOOTH_SIDES) {
				if (kx==sides-1 && (sides&1)) {
					grp = (1<<2);
				} else {
					grp = (kx&1) ? (1<<0) : (1<<1);
					}
			} else 
			if (smooth==SMOOTH_STRIPES) {
				if (ix==segs-1 && (segs&1)) {
					grp = (1<<2);
				} else {
					grp = (ix&1) ? (1<<0) : (1<<1);
					}
			} else 
			if (smooth > 0) {
				grp = 1;
				}

			mesh.faces[nf].setEdgeVisFlags(0,1,1);
			mesh.faces[nf].setSmGroup(grp);
			mesh.faces[nf].setMatID(0);
			mesh.faces[nf++].setVerts( na,nc,nb);

			mesh.faces[nf].setEdgeVisFlags(1,1,0);
			mesh.faces[nf].setSmGroup(grp);
			mesh.faces[nf].setMatID(0);
			mesh.faces[nf++].setVerts(na,nd,nc);
			}
	 	}

	if (doPie) {		
		na = nv -2;
		for(ix=0; ix<sides; ++ix) {
			nb = ix;
			nc = (ix==(sides-1))?0:ix+1;
			mesh.faces[nf].setEdgeVisFlags(0,1,0);
			mesh.faces[nf].setSmGroup((1<<3));
			mesh.faces[nf].setMatID(1);
            if (usePhysUVs)
                startSliceFaces.Set(nf);
			mesh.faces[nf++].setVerts(na,nc,nb);
			}
		
		na = nv -1;
		jx = sides*(segs-1);
		for(ix=0; ix<sides; ++ix) {
			nb = jx+ix;
			nc = (ix==(sides-1))?jx:nb+1;
			mesh.faces[nf].setEdgeVisFlags(0,1,0);
			mesh.faces[nf].setSmGroup((1<<3));
			mesh.faces[nf].setMatID(2);
            if (usePhysUVs)
                endSliceFaces.Set(nf);
			mesh.faces[nf++].setVerts(na,nb,nc);
			}
		}

	
	// UVWs -------------------
	
	if (genUVs) {
        float uScale = usePhysUVs ? ((float) 2.0f * PI * radius) : 1.0f;
        float vScale = usePhysUVs ? ((float) 2.0f * PI * radius2) : 1.0f;
        if (doPie) {
            float pieScale = float(totalPie/(2.0*PI));
            uScale *= float(pieScale);
        }

		nv=0;
		for(ix=0; ix<=segs-doPie; ix++) {
			for (jx=0; jx<=sides; jx++) {
                if (usePhysUVs)
                    mesh.setTVert(nv++,uScale*(1.0f - float(ix)/float(segs-doPie)),vScale*float(jx)/float(sides),0.0f);
                else
				mesh.setTVert(nv++,float(jx)/float(sides),float(ix)/float(segs),0.0f);
				}
			}
		int pie1 = 0;
		int pie2 = 0;
		if (doPie) {
			pie1 = nv;
            if (usePhysUVs)
                mesh.setTVert(nv++,0.0f,vScale*0.5f,0.0f);
            else
			mesh.setTVert(nv++,0.5f,1.0f,0.0f);
			pie2 = nv;
            if (usePhysUVs)
                mesh.setTVert(nv++,uScale*0.5f,vScale*0.0f,0.0f);
            else
                mesh.setTVert(nv++,1.0f,0.5f,0.0f);
			}				
		
		nf=0;
		for(ix=0; ix<segs-doPie; ix++) {
			na = ix*(sides+1);
			nb = (ix+1)*(sides+1);
			for (jx=0; jx<sides; jx++) {
				mesh.tvFace[nf++].setTVerts(na,nb+1,nb);
				mesh.tvFace[nf++].setTVerts(na,na+1,nb+1);
				na++;
				nb++;
				}
			}
		if (doPie) {						
            if (usePhysUVs) {
                Matrix3 tm = RotateZMatrix(startAng) * RotateXMatrix(float(-PI/2.0));
                tm.Scale(Point3(-1.0f, 1.0f, 1.0f));
                MakeMeshCapTexture(mesh, tm, startSliceFaces, usePhysUVs);
                tm = RotateZMatrix(ang) * RotateXMatrix(float(-PI/2.0));
                MakeMeshCapTexture(mesh, tm, endSliceFaces, usePhysUVs);
            } else {
			for (jx=0; jx<sides; jx++) {
				mesh.tvFace[nf++].setTVerts(pie1,jx+1,jx);				
				}			
			nb = (sides+1)*(segs-1);
			for (jx=0; jx<sides; jx++) {
				mesh.tvFace[nf++].setTVerts(pie2,nb,nb+1);
				nb++;
				}
			}
		}
		}

	mesh.InvalidateTopologyCache();
	}
Exemplo n.º 22
0
	inline BOOL HitLimit(void) { return CountValue() == LimitValue(); }
Exemplo n.º 23
0
bool ExtrudeMod::BuildAMSolidFromShape(TimeValue t,ModContext &mc, ObjectState * os, IGeomImp* igeom) 
{
	ShapeObject *shape = (ShapeObject *)os->obj;

	float amount;

	pblock->GetValue(PB_AMOUNT,t,amount,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);
	if(fabs(amount)<MIN_EXT)
		amount = MIN_EXT;

	// 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;
	PolyShape pShape;
	shape->MakePolyShape(t, pShape, PSHAPE_BUILTIN_STEPS, true);
	ShapeHierarchy hier;
	pShape.OrganizeCurves(t, &hier);
	// Need to flip the reversed curves in the shape!
	pShape.Reverse(hier.reverse);

	//Now add the extrusion for each polygon
	bool res = false;//assume the best

	//make a solid to hold our work
	Object* solid = (Object*)CreateInstance(GEOMOBJECT_CLASS_ID, GENERIC_AMSOLID_CLASS_ID);
	IGeomImp* workgeom = NULL;
	assert(solid);
	if(solid)
	{
		workgeom = (IGeomImp*)(solid->GetInterface(I_GEOMIMP));
		assert(workgeom);
	}

	for(int i=0;i<pShape.numLines; i++)
	{
		PolyLine poly = pShape.lines[i];
		if(poly.numPts)
			poly.pts[0].aux = poly.flags;
		bool localres  = workgeom->createExtrusion(poly.pts, poly.numPts, amount, smooth, genMatIDs, useShapeIDs);

		if(localres)
		{
			//need to figure out how deeply nested this shape is
			//order is this value with zero meaning not nested
			HierarchyEntry *entry = hier.hier.FindEntry(i);
			assert(entry);
			int order = 0;
			while(entry && (entry->parent != (HierarchyEntry *)-1))
			{
				entry = entry->parent;
				++order;
			}

			if(order%2)
				igeom->operator-=(*workgeom);
			else
				igeom->operator+=(*workgeom);
		}
		res |= localres;
	}

	//do some cleanup
	if(workgeom)
	{
		assert(solid);
		solid->ReleaseInterface(I_GEOMIMP, workgeom);
		solid->DeleteMe();
	}
	return res;
}
Exemplo n.º 24
0
void CExtObject::BuildMesh(TimeValue t)
	{	
	int hsegs,tsegs,ssegs,bsegs,wsegs;
	float height,toplen,sidelen,botlen,topwidth,sidewidth,botwidth;
	int genUVs;	

	// Start the validity interval at forever and widdle it down.
	FixTopWidth(pblock,t,(pmapParam?pmapParam->GetHWnd():NULL),increate);
	FixBotWidth(pblock,t,(pmapParam?pmapParam->GetHWnd():NULL),increate);
	FixSideWidth(pblock,t,(pmapParam?pmapParam->GetHWnd():NULL),increate);
	ivalid = FOREVER;
	
	pblock->GetValue(PB_HSEGS,t,hsegs,ivalid);
	pblock->GetValue(PB_TSEGS,t,tsegs,ivalid);
	pblock->GetValue(PB_SSEGS,t,ssegs,ivalid);
	pblock->GetValue(PB_BSEGS,t,bsegs,ivalid);
	pblock->GetValue(PB_WSEGS,t,wsegs,ivalid);
	pblock->GetValue(PB_TOPLENGTH,t,toplen,ivalid);
	pblock->GetValue(PB_SIDELENGTH,t,sidelen,ivalid);
	pblock->GetValue(PB_BOTLENGTH,t,botlen,ivalid);
	pblock->GetValue(PB_TOPWIDTH,t,topwidth,ivalid);
	pblock->GetValue(PB_SIDEWIDTH,t,sidewidth,ivalid);
	pblock->GetValue(PB_BOTWIDTH,t,botwidth,ivalid);
	pblock->GetValue(PB_HEIGHT,t,height,ivalid);
	pblock->GetValue(PB_GENUVS,t,genUVs,ivalid);
	LimitValue(height, MIN_HEIGHT, BMAX_HEIGHT);
	LimitValue(toplen, MIN_HEIGHT, BMAX_LENGTH);
	LimitValue(sidelen, MIN_HEIGHT,BMAX_WIDTH);
	LimitValue(botlen, MIN_HEIGHT, BMAX_HEIGHT);
	LimitValue(topwidth, BMIN_LENGTH,BMAX_LENGTH);
	LimitValue(sidewidth, BMIN_WIDTH,BMAX_WIDTH);
	LimitValue(botwidth, BMIN_HEIGHT,BMAX_HEIGHT);
	LimitValue(hsegs, MIN_SEGMENTS, MAX_SEGMENTS);
	LimitValue(tsegs, MIN_SEGMENTS, MAX_SEGMENTS);
	LimitValue(ssegs, MIN_SEGMENTS, MAX_SEGMENTS);
	LimitValue(bsegs, MIN_SEGMENTS, MAX_SEGMENTS);
	LimitValue(wsegs, MIN_SEGMENTS, MAX_SEGMENTS);
	
	BuildCExtMesh(mesh,hsegs,tsegs,ssegs,bsegs,wsegs,height,
		toplen,sidelen,botlen,topwidth,sidewidth,botwidth, genUVs,createmeth,GetUsePhysicalScaleUVs());
	}
Exemplo n.º 25
0
void SelObjIds::select(TimeValue t, CompMap &compMap, Bitmap *bm, RenderGlobalContext *gc)
{
	float fTemp;
	ULONG chanType;

	mp_srcObjId = (WORD *)bm->GetChannel(BMM_CHAN_NODE_ID, chanType);
	if (chanType != BMM_CHAN_TYPE_16)
		mp_blurMgr->blurError(IDS_ERR_GBUF_INVALID);
	mp_srcColor = (Color24*)bm->GetChannel(BMM_CHAN_COLOR, chanType);
	if (chanType != BMM_CHAN_TYPE_24)
		mp_blurMgr->blurError(IDS_ERR_GBUF_INVALID);

	// if source bitmap has changed since last call
	if ( m_lastBMModifyID != bm->GetModifyID() )
	{
		m_lastBMModifyID = bm->GetModifyID();
		m_selectValid = m_featherValid = m_compValid = false;
		if ( (bm->Width() != m_imageW) || (bm->Height() != m_imageH) )
		{
			m_imageW = bm->Width();
			m_imageH = bm->Height();
			m_imageSz = m_imageW * m_imageH;
			if (m_imageSz > m_mapSz)
			{
				if (mp_radMap)
					delete[] mp_radMap;
				mp_radMap = new float[m_imageSz];
				m_mapSz = m_imageSz;
			}
		}
	}

	if (!m_selectValid)
	{
		// make list of desired ids
		m_idCount = mp_blurMgr->getSelTabCount(prmObjIdsIds);
		if (m_idCount > m_idListSz)
		{
			if (mp_idList)
				delete[] mp_idList;
			mp_idList = new int[m_idCount];
			m_idListSz = m_idCount;
		}
		for (int i=0; i<m_idCount; i++)
			mp_blurMgr->getSelValue(prmObjIdsIds, t, mp_idList[i], FOREVER, i);

		// get luminance parameters
		mp_blurMgr->getSelValue(prmObjIdsLumMin, t, fTemp, FOREVER);
		LimitValue(fTemp, 0.0f, 100.0f); // mjm - 9.30.99
		m_min = fTemp*PERCENT2DEC;

		mp_blurMgr->getSelValue(prmObjIdsLumMax, t, fTemp, FOREVER);
		LimitValue(fTemp, 0.0f, 100.0f); // mjm - 9.30.99
		m_max = fTemp*PERCENT2DEC;

		// select the appropriate pixels
		m_selectValid = doSelect();
	}
	
	if (!m_featherValid)
	{
		mp_blurMgr->getSelValue(prmObjIdsFeathRad, t, fTemp, FOREVER);
		LimitValue(fTemp, 0.0f, 1000.0f); // mjm - 9.30.99
		m_feathRad = (int)floor(max(m_imageW, m_imageH)*(fTemp*PERCENT2DEC));
		m_featherValid = doFeather();
	}

	mp_blurMgr->getSelValue(prmObjIdsBrighten, t, fTemp, FOREVER);
	LimitValue(fTemp, 0.0f, 1000.0f); // mjm - 9.30.99
	m_brighten = fTemp*PERCENT2DEC;

	mp_blurMgr->getSelValue(prmObjIdsBlend, t, fTemp, FOREVER);
	LimitValue(fTemp, 0.0f, 100.0f); // mjm - 9.30.99
	m_blend = fTemp*PERCENT2DEC;

	m_compValid = doComposite(t, compMap);
}
Exemplo n.º 26
0
void ChBoxObject::BuildMesh(TimeValue t)
	{
	int smooth,dsegs,vertices;
	int WLines,HLines,DLines,CLines,VertexPerSlice;
	int VertexPerFace,FacesPerSlice,chamferend;
	float usedw,usedd,usedh,cradius,zdelta,CurRadius;
	Point3 va,vb,p;
	float depth, width, height;
	int genUVs = 1,sqvertex,CircleLayers;
	BOOL bias = 0,minusd;

	// Start the validity interval at forever and widdle it down.
	ivalid = FOREVER;	
	pblock->GetValue(PB_LENGTH,t,height,ivalid);
	pblock->GetValue(PB_WIDTH,t,width,ivalid);
	pblock->GetValue(PB_HEIGHT,t,depth,ivalid);
	minusd=depth<0.0f;
	depth=(float)fabs(depth);
	pblock->GetValue(PB_RADIUS,t,cradius,ivalid);
	pblock->GetValue(PB_LSEGS,t,hsegs,ivalid);
	pblock->GetValue(PB_WSEGS,t,wsegs,ivalid);
	pblock->GetValue(PB_HSEGS,t,dsegs,ivalid);
	pblock->GetValue(PB_CSEGS,t,csegs,ivalid);
	pblock->GetValue(PB_GENUVS,t,genUVs,ivalid);
	pblock->GetValue(PB_SMOOTH,t,smooth,ivalid);
	
	LimitValue(csegs, MIN_SEGMENTS, MAX_SEGMENTS);
	LimitValue(dsegs, MIN_SEGMENTS, MAX_SEGMENTS);
	LimitValue(wsegs, MIN_SEGMENTS, MAX_SEGMENTS);
	LimitValue(hsegs, MIN_SEGMENTS, MAX_SEGMENTS);

	smooth=(smooth>0?1:0);
	mesh.setSmoothFlags(smooth);
	float twocrad,usedm,mindim=(height>width?(width>depth?depth:width):(height>depth?depth:height));
	usedm=mindim-2*cradius;
	if (usedm<0.01f) cradius=(mindim-0.01f)/2.0f;
	twocrad=2.0f*cradius;
    usedh=height-twocrad;
    usedw=width-twocrad;
    usedd=depth-twocrad;
	float cangincr=PI/(2.0f*csegs),cudelta,udist;
    CircleLayers=csegs;
	cudelta=cradius*(float)sqrt(2.0f*(1.0f-(float)cos(cangincr)));
	udist=4.0f*csegs*cudelta+2.0f*width+2.0f*height-4.0f*cradius;
	chamferinfo[0].surface=1;chamferinfo[0].deltavert=1;
	chamferinfo[1].surface=2;chamferinfo[1].deltavert=1;
	chamferinfo[2].surface=1;chamferinfo[2].deltavert=-1;
	chamferinfo[3].surface=2;chamferinfo[3].deltavert=-1;
    WLines=wsegs-1;
    HLines=hsegs-1;
    DLines=dsegs-1;
    CLines=csegs+1;
    VertexPerSlice=2*(WLines+HLines)+4*CLines;
/* WLines*HLines on middle, 2*Clines*(WLines+HLines) on sides, 4*CLines*csegs+4 for circles */
    VertexPerFace=WLines*HLines+2*CLines*(WLines+HLines+2*csegs)+4;
    vertices=VertexPerFace*2+VertexPerSlice*DLines;
    sqvertex=(wsegs+1)*(hsegs+1);
/* 4 vertices, 2 faces/cseg + 2 each hseg & wseg sides, each seg w/ 2 faces*/
    SidesPerSlice=2*(2*csegs+hsegs+wsegs);
    FacesPerSlice=SidesPerSlice*2;
/* this one only has 1 face/ cseg */
    topchamferfaces=4*(csegs+hsegs+wsegs);
/*top chamfer + top face(2 faces/seg)(*2 for bottom) plus any depth faces*/
    maxfaces=2*(topchamferfaces+2*hsegs*wsegs)+(2*(CircleLayers-1)+dsegs)*FacesPerSlice;
    chamferstart=2*hsegs*wsegs;
    chamferend=chamferstart+topchamferfaces+(CircleLayers-1)*FacesPerSlice;
    chamferinfo[0].deltavert +=wsegs;
    chamferinfo[2].deltavert -=wsegs;
	int bottomvertex,vertexnum,tverts;
	int twomapped,endvert=vertices+(twomapped=2*VertexPerSlice);
	float xmax,ymax;
	mesh.setNumVerts(vertices);
	mesh.setNumFaces(maxfaces);
	tverts=endvert+DLines+2;
	if (genUVs)
	{ mesh.setNumTVerts(tverts);
	  mesh.setNumTVFaces(maxfaces);
	}
	else
	{ mesh.setNumTVerts(0);
	  mesh.setNumTVFaces(0);
	}
    zdelta=depth/2;
    wsegcount=0;vertexnum=0;
    bottomvertex=vertices-1;
    CornerPt.z=zdelta;
    CornerPt.x=(xmax=width/2)-cradius;
    CornerPt.y=(ymax=height/2)-cradius;
    NewPt.x=Toppt.x=-CornerPt.x;
    NewPt.y=Toppt.y=CornerPt.y;
    NewPt.z=Toppt.z=zdelta;
      /* Do top and bottom faces */
	hincr=usedh/hsegs;		//yincr
	wincr=usedw/wsegs;		//xincr
    BOOL usePhysUVs = GetUsePhysicalScaleUVs();

	int segcount,topvertex,tvcounter=0,tvbottom=endvert-1;
	float udiv=usePhysUVs ? 1.0f : 2.0f*xmax,vdiv=usePhysUVs ? 1.0f :2.0f*ymax, u = 0.0f, v = 0.0f;
	for (hseg=0;hseg<=hsegs;hseg++)
	{ if (hseg>0) 
	  {NewPt.y=(hseg==hsegs?-CornerPt.y:Toppt.y-hseg*hincr); NewPt.x=Toppt.x; }
	  for (segcount=0;segcount<=wsegs;segcount++)
	  { /* make top point */
	   NewPt.z=Toppt.z;
       NewPt.x=(segcount==wsegs?CornerPt.x:Toppt.x+segcount*wincr);
	   if (genUVs) 
		 mesh.setTVert(vertexnum,u=(xmax+NewPt.x)/udiv,v=(ymax+NewPt.y)/vdiv,0.0f);
	   mesh.setVert(vertexnum++,NewPt);
		/* make bottom pt */
       NewPt.z=-zdelta;
	   if (genUVs) 
	     mesh.setTVert(tvbottom--,u,(usePhysUVs ? 2.0f*ymax : 1.0f)-v,0.0f);
	   mesh.setVert(bottomvertex--,NewPt);
	  }
	}
    /* start on the chamfer */
	int layer,vert;
    layer=0;
    hseg=0;
	tvcounter=vertexnum;
    bottomvertex-=(VertexPerSlice-1);
    topvertex=vertexnum;
	BOOL done = FALSE,atedge = FALSE;
	float dincr=usedd/dsegs,cincr=2.0f*CircleLayers,RotationAngle;
	float dx,dy;
	int cornervert[4],PtRotation;
     for (layer=1;layer<=CircleLayers;layer++)	   /* add chamfer layer */
	 { if (layer==CircleLayers)	{zdelta=cradius;CurRadius=cradius;}
	   else
	   { RotationAngle=(PI*layer)/cincr;
	 	 zdelta=cradius-(cradius*(float)cos(RotationAngle));
		 CurRadius=cradius*(float)sin(RotationAngle);
	   }
	   zdelta=CornerPt.z-zdelta;
       atedge=(layer==CircleLayers);
	   int vfromedge=0,oldside=0,vfromstart=0;
	   sidenum=0;
	   float u1 = 0.0f, v1 = 0.0f;
	   BOOL atstart=TRUE;
       while (vertexnum<topvertex+csegs)	/* add vertex loop */
	   { PtRotation=hseg=wsegcount=0;done=FALSE;
         RotationAngle=(vertexnum-topvertex)*cangincr;
         curvertex=vert=vertexnum;
		 NewPt.x=Toppt.x-(dx=CurRadius*(float)sin(RotationAngle));
         NewPt.y=Toppt.y+(dy=CurRadius*(float)cos(RotationAngle));
         NewPt.z=zdelta;
		 while (!done)
		 { mesh.setVert(vert,NewPt);
		   if (genUVs) 
		    mesh.setTVert(vert,u1=(xmax+NewPt.x)/udiv,v1=(ymax+NewPt.y)/vdiv,0.0f);
           /* reflected vertex to second face */
           vert=bottomvertex+curvertex-topvertex;
           NewPt.z=-zdelta;
		   mesh.setVert(vert,NewPt);
		   if (genUVs)
		     mesh.setTVert(vert+twomapped,u1,(usePhysUVs ? 2.0f*ymax : 1.0f)-v1,0.0f);
           if ((atedge)&&(DLines>0))	 /* add non-corner points */
		    for (segcount=1;segcount<=DLines;segcount++)
		    { NewPt.z=zdelta-segcount*dincr;
		      mesh.setVert(vert=curvertex+VertexPerSlice*segcount,NewPt);
		    }
		   /* Rotate Pt */
		   done=PtRotation>5;
		   if (done == FALSE)
		   { if (vertexnum==topvertex) 
		     { FillinSquare(&PtRotation,cornervert,CurRadius);
		       if (curvertex==topvertex+VertexPerSlice-1) (PtRotation)=6;
		     }
			 else
				CalculateNewPt(dx,dy,&PtRotation,cornervert,vertexnum-topvertex);
		     vert=curvertex;
			 NewPt.z=zdelta;
		   }
		 }
	     vertexnum++;	   /* done rotation */
	   }
       vertexnum=topvertex +=VertexPerSlice;
       bottomvertex -=VertexPerSlice;  
	}
	float dfromedge=0.0f;
	int tvnum,j,i,chsegs=csegs+1,cwsegs=wsegs;
	if (genUVs)
	{ u=0.0f;
	  dfromedge=-cudelta;
	  tvnum=vertexnum;
	  vertexnum=topvertex-VertexPerSlice;
      float uDenom = usePhysUVs ? 1.0f : udist;
      float vScale = usePhysUVs ? usedd : 1.0f;
      float maxU = 0.0f;
	  for (j=0;j<2;j++)
	  {
     int gverts;
	  for (gverts=0;gverts<chsegs;gverts++)
	  {	dfromedge+=cudelta;
		mesh.setTVert(tvnum,u=dfromedge/uDenom,vScale,0.0f);
        if (u > maxU) maxU = u;
	    for (i=1;i<=dsegs;i++)
	     mesh.setTVert(tvnum+VertexPerSlice*i,u,vScale*(1.0f-(float)i/dsegs),0.0f);
		vertexnum++;
		tvnum++;
	  }
	  chsegs=csegs;
	  for (gverts=0;gverts<hsegs;gverts++)
	  { dfromedge+=(float)fabs(mesh.verts[vertexnum].y-mesh.verts[vertexnum-1].y);
		mesh.setTVert(tvnum,u=dfromedge/uDenom,vScale,0.0f);
        if (u > maxU) maxU = u;
	    for (i=1;i<=dsegs;i++)
	     mesh.setTVert(tvnum+VertexPerSlice*i,u,vScale*(1.0f-(float)i/dsegs),0.0f);
		vertexnum++;
		tvnum++;
	  }
	  for (gverts=0;gverts<csegs;gverts++)
	  {	dfromedge+=cudelta;
		mesh.setTVert(tvnum,u=dfromedge/uDenom,vScale,0.0f);
        if (u > maxU) maxU = u;
	    for (i=1;i<=dsegs;i++)
	     mesh.setTVert(tvnum+VertexPerSlice*i,u,vScale*(1.0f-(float)i/dsegs),0.0f);
		vertexnum++;
		tvnum++;
	  }
	  if (j==1) cwsegs--;
	  for (gverts=0;gverts<cwsegs;gverts++)
	  { dfromedge+=(float)fabs(mesh.verts[vertexnum].x-mesh.verts[vertexnum-1].x);
		mesh.setTVert(tvnum,u=dfromedge/uDenom,vScale,0.0f);
        if (u > maxU) maxU = u;
	    for (i=1;i<=dsegs;i++)
	     mesh.setTVert(tvnum+VertexPerSlice*i,u,vScale*(1.0f-(float)i/dsegs),0.0f);
		vertexnum++;
		tvnum++;
	  }
	  }
	  int lastvert=endvert;
      float uScale = usePhysUVs ? udist-4*cradius : 1.0f;
	  mesh.setTVert(lastvert++,uScale, vScale,0.0f);
	  for (j=1;j<dsegs;j++)
	    mesh.setTVert(lastvert++,uScale, vScale*(1.0f-(float)j/dsegs),0.0f);
	  mesh.setTVert(lastvert,uScale, 0.0f,0.0f);
	}
    /* all vertices calculated - Now specify faces*/
	 int tvdelta=0;
    sidenum=topnum=face=fcount=scount=circleseg=0;
    curvertex=wsegs+1;
    firstface=layer=1;
//	smooth=(csegs>1?1:0);
    tstartpt=cstartpt=endpt=0;
    boxpos=topsquare;cstartpt=chamferinfo[0].deltavert;
	AddFace(&mesh.faces[face],smooth,tvdelta,&mesh.tvFace[face],genUVs);
      while (face<chamferstart)   /* Do Square Layer */
	  { firstface=!firstface;
		AddFace(&mesh.faces[face],smooth,tvdelta,&mesh.tvFace[face],genUVs);
      }  
      boxpos=messyedge;firstface=1;
      topnum=tstartpt=0;
      cstartpt=curvertex=topnum+sqvertex;circleseg=1;
      endpt=hsegs*(wsegs+1);
      /* Do Chamfer */
	  while (face<chamferend)
      { AddFace(&mesh.faces[face],smooth,tvdelta,&mesh.tvFace[face],genUVs);
		if (circleseg==0) firstface=!firstface;
	  }
      fcount=scount=0;
      boxpos=middle;tvdelta+=VertexPerSlice;
     /*Do box sides */
	  int tpt,lastv=tverts-1;
	  BOOL inside=TRUE;
      while (face<maxfaces-chamferstart-topchamferfaces)
	  { tpt=face;
		AddFace(&mesh.faces[face],smooth,tvdelta,&mesh.tvFace[face],genUVs);
		if (genUVs && inside)
		{ if ((firstface)&&(mesh.tvFace[tpt].t[2]<mesh.tvFace[tpt].t[1]))
			mesh.tvFace[tpt].t[2]=endvert+1;
		  else if (mesh.tvFace[tpt].t[2]<mesh.tvFace[tpt].t[0])
		  { mesh.tvFace[tpt].t[1]=endvert+1;
			mesh.tvFace[tpt].t[2]=endvert;
			endvert++;
			inside=endvert<lastv;
			if (inside==FALSE) 
			  tvdelta+=VertexPerSlice;
		  }
		}	
		firstface=!firstface;
	  }
      /* back in chamfer */
      circleseg=2;firstface=0;
      boxpos=bottomedge;
      sidenum=0;tstartpt=topnum;
      cstartpt=curvertex=vertices-1;
      endpt=cstartpt-hsegs*chamferinfo[0].deltavert;
	  while (face<maxfaces-chamferstart)  /* Do Second Chamfer */
	  { AddFace(&mesh.faces[face],smooth,tvdelta,&mesh.tvFace[face],genUVs);
		if (circleseg==0) firstface=!firstface;
	  }
      boxpos=bottomsquare;
      curvertex=topnum;
      topnum=curvertex+chamferinfo[0].deltavert;
      firstface=1;fcount=0;
	  while (face<maxfaces)
	  { AddFace(&mesh.faces[face],smooth,tvdelta,&mesh.tvFace[face],genUVs);
        firstface=!firstface;
	  }
    float deltaz=(minusd?-depth/2.0f:depth/2.0f);
	for (i=0;i<vertices;i++)
	{ mesh.verts[i].z+=deltaz;
	}
	mesh.InvalidateTopologyCache();
	}
Exemplo n.º 27
0
void RelaxMod::ModifyObject(TimeValue t, ModContext &mc, ObjectState * os, INode *node) {	
	// Get our personal validity interval...
	Interval valid = GetValidity(t);
	// and intersect it with the channels we use as input (see ChannelsUsed)
	valid &= os->obj->ChannelValidity (t, GEOM_CHAN_NUM);
	valid &= os->obj->ChannelValidity (t, TOPO_CHAN_NUM);
	valid &= os->obj->ChannelValidity (t, SUBSEL_TYPE_CHAN_NUM);
	valid &= os->obj->ChannelValidity (t, SELECT_CHAN_NUM);
	Matrix3 modmat,minv;
	
	if (mc.localData == NULL) mc.localData = new RelaxModData;
	RelaxModData *rd = (RelaxModData *) mc.localData;

	TriObject *triObj = NULL;
	PatchObject *patchObj = NULL;
	PolyObject *polyObj = NULL;
	BOOL converted = FALSE;

	// For version 4 and later, we process patch or poly meshes as they are and pass them on. 
	// Earlier versions converted to TriMeshes (done below).
	// For adding other new types of objects, add them here!
#ifndef NO_PATCHES
	if(version >= RELAXMOD_VER4 && os->obj->IsSubClassOf(patchObjectClassID)) {
		patchObj = (PatchObject *)os->obj;
		}
	else	// If it's a TriObject, process it
#endif // NO_PATCHES
	if(os->obj->IsSubClassOf(triObjectClassID)) {
		triObj = (TriObject *)os->obj;
	}
	else if (os->obj->IsSubClassOf (polyObjectClassID)) {
		polyObj = (PolyObject *) os->obj;
	}
	else	// If it can convert to a TriObject, do it
	if(os->obj->CanConvertToType(triObjectClassID)) {
		triObj = (TriObject *)os->obj->ConvertToType(t, triObjectClassID);
		converted = TRUE;
		}
	else
		return;		// We can't deal with it!

	Mesh *mesh = triObj ? &(triObj->GetMesh()) : NULL;
#ifndef NO_PATCHES
	PatchMesh &pmesh = patchObj ? patchObj->GetPatchMesh(t) : *((PatchMesh *)NULL);
#else
	PatchMesh &pmesh = *((PatchMesh *)NULL);
#endif // NO_PATCHES

	float relax, wtdRelax; // mjm - 4.8.99
	int iter;
	BOOL boundary, saddle;

	pblock->GetValue (PB_RELAX,  t, relax,	 FOREVER);
	pblock->GetValue (PB_ITER,	 t, iter,	 FOREVER);
	pblock->GetValue (PB_BOUNDARY, t, boundary, FOREVER);
	pblock->GetValue (PB_SADDLE, t, saddle, FOREVER);

	LimitValue (relax, MIN_RELAX, MAX_RELAX);
	LimitValue (iter, MIN_ITER, MAX_ITER);

	if(triObj) {
		int i, j, max;
		DWORD selLevel = mesh->selLevel;
		// mjm - 4.8.99 - add support for soft selection
		// sca - 4.29.99 - extended soft selection support to cover EDGE and FACE selection levels.
		float *vsw = (selLevel!=MESH_OBJECT) ? mesh->getVSelectionWeights() : NULL;

		if (rd->ivalid.InInterval(t) && (mesh->numVerts != rd->vnum)) {
			// Shouldn't happen, but does with Loft bug and may with other bugs.
			rd->ivalid.SetEmpty ();
		}

		if (!rd->ivalid.InInterval(t)) {
			rd->SetVNum (mesh->numVerts);
			for (i=0; i<rd->vnum; i++) {
				rd->fnum[i]=0;
				rd->nbor[i].ZeroCount();
			}
			rd->sel.ClearAll ();
			DWORD *v;
			int k1, k2, origmax;
			for (i=0; i<mesh->numFaces; i++) {
				v = mesh->faces[i].v;
				for (j=0; j<3; j++) {
					if ((selLevel==MESH_FACE) && mesh->faceSel[i]) rd->sel.Set(v[j]);
					if ((selLevel==MESH_EDGE) && mesh->edgeSel[i*3+j]) rd->sel.Set(v[j]);
					if ((selLevel==MESH_EDGE) && mesh->edgeSel[i*3+(j+2)%3]) rd->sel.Set(v[j]);
					origmax = max = rd->nbor[v[j]].Count();
					rd->fnum[v[j]]++;
					for (k1=0; k1<max; k1++) if (rd->nbor[v[j]][k1] == v[(j+1)%3]) break;
					if (k1==max) { rd->nbor[v[j]].Append (1, v+(j+1)%3, 1); max++; }
					for (k2=0; k2<max; k2++) if (rd->nbor[v[j]][k2] == v[(j+2)%3]) break;
					if (k2==max) { rd->nbor[v[j]].Append (1, v+(j+2)%3, 1); max++; }
					if (max>origmax) rd->vis[v[j]].SetSize (max, TRUE);
					if (mesh->faces[i].getEdgeVis (j)) rd->vis[v[j]].Set (k1);
					else if (k1>=origmax) rd->vis[v[j]].Clear (k1);
					if (mesh->faces[i].getEdgeVis ((j+2)%3)) rd->vis[v[j]].Set (k2);
					else if (k2>= origmax) rd->vis[v[j]].Clear (k2);
				}
			}
	// mjm - begin - 4.8.99
	//		if (selLevel==MESH_VERTEX) rd->sel = mesh->vertSel;
			if (selLevel==MESH_VERTEX)
				rd->sel = mesh->vertSel;
			else if (selLevel==MESH_OBJECT)
				rd->sel.SetAll ();
	// mjm - end
			rd->ivalid  = os->obj->ChannelValidity (t, TOPO_CHAN_NUM);
			rd->ivalid &= os->obj->ChannelValidity (t, SUBSEL_TYPE_CHAN_NUM);
			rd->ivalid &= os->obj->ChannelValidity (t, SELECT_CHAN_NUM);
		}

		Tab<float> vangles;
		if (saddle) vangles.SetCount (rd->vnum);
		Point3 *hold = new Point3[rd->vnum];
		int act;
		for (int k=0; k<iter; k++) {
			for (i=0; i<rd->vnum; i++) hold[i] = triObj->GetPoint(i);
			if (saddle) mesh->FindVertexAngles (vangles.Addr(0));
			for (i=0; i<rd->vnum; i++) {
	// mjm - begin - 4.8.99
	//			if ((selLevel!=MESH_OBJECT) && (!rd->sel[i])) continue;
				if ( (!rd->sel[i] ) && (!vsw || vsw[i] == 0) ) continue;
	// mjm - end
				if (saddle && (vangles[i] <= 2*PI*.99999f)) continue;
				max = rd->nbor[i].Count();
				if (boundary && (rd->fnum[i] < max)) continue;
				if (max<1) continue;
				Point3 avg(0.0f, 0.0f, 0.0f);
				for (j=0,act=0; j<max; j++) {
					if (!rd->vis[i][j]) continue;
					act++;
					avg += hold[rd->nbor[i][j]];
				}
				if (act<1) continue;
	// mjm - begin - 4.8.99
				wtdRelax = (!rd->sel[i]) ? relax * vsw[i] : relax;
				triObj->SetPoint (i, hold[i]*(1-wtdRelax) + avg*wtdRelax/((float)act));
	//			triObj->SetPoint (i, hold[i]*(1-relax) + avg*relax/((float)act));
	// mjm - end
			}
		}
		delete [] hold;
	}

	if (polyObj) {
		int i, j, max;
		MNMesh & mm = polyObj->mm;
		float *vsw = (mm.selLevel!=MNM_SL_OBJECT) ? mm.getVSelectionWeights() : NULL;

		if (rd->ivalid.InInterval(t) && (mm.numv != rd->vnum)) {
			// Shouldn't happen, but does with Loft bug and may with other bugs.
			rd->ivalid.SetEmpty ();
		}

		if (!rd->ivalid.InInterval(t)) {
			rd->SetVNum (mm.numv);
			for (i=0; i<rd->vnum; i++) {
				rd->fnum[i]=0;
				rd->nbor[i].ZeroCount();
			}
			rd->sel = mm.VertexTempSel ();
			int k1, k2, origmax;
			for (i=0; i<mm.numf; i++) {
				int deg = mm.f[i].deg;
				int *vtx = mm.f[i].vtx;
				for (j=0; j<deg; j++) {
					Tab<DWORD> & nbor = rd->nbor[vtx[j]];
					origmax = max = nbor.Count();
					rd->fnum[vtx[j]]++;
					DWORD va = vtx[(j+1)%deg];
					DWORD vb = vtx[(j+deg-1)%deg];
					for (k1=0; k1<max; k1++) if (nbor[k1] == va) break;
					if (k1==max) { nbor.Append (1, &va, 1); max++; }
					for (k2=0; k2<max; k2++) if (nbor[k2] == vb) break;
					if (k2==max) { nbor.Append (1, &vb, 1); max++; }
				}
			}
			rd->ivalid = os->obj->ChannelValidity (t, TOPO_CHAN_NUM);
			rd->ivalid &= os->obj->ChannelValidity (t, SUBSEL_TYPE_CHAN_NUM);
			rd->ivalid &= os->obj->ChannelValidity (t, SELECT_CHAN_NUM);
		}

		Tab<float> vangles;
		if (saddle) vangles.SetCount (rd->vnum);
		Tab<Point3> hold;
		hold.SetCount (rd->vnum);
		int act;
		for (int k=0; k<iter; k++) {
			for (i=0; i<rd->vnum; i++) hold[i] = mm.P(i);
			if (saddle) FindVertexAngles (mm, vangles.Addr(0));
			for (i=0; i<rd->vnum; i++) {
				if ((!rd->sel[i]) && (!vsw || vsw[i] == 0) ) continue;
				if (saddle && (vangles[i] <= 2*PI*.99999f)) continue;
				max = rd->nbor[i].Count();
				if (boundary && (rd->fnum[i] < max)) continue;
				if (max<1) continue;
				Point3 avg(0.0f, 0.0f, 0.0f);
				for (j=0,act=0; j<max; j++) {
					act++;
					avg += hold[rd->nbor[i][j]];
				}
				if (act<1) continue;
				wtdRelax = (!rd->sel[i]) ? relax * vsw[i] : relax;
				polyObj->SetPoint (i, hold[i]*(1-wtdRelax) + avg*wtdRelax/((float)act));
			}
		}
	}

#ifndef NO_PATCHES
	else
	if(patchObj) {
		int i, j, max;
		DWORD selLevel = pmesh.selLevel;
		// mjm - 4.8.99 - add support for soft selection
		// sca - 4.29.99 - extended soft selection support to cover EDGE and FACE selection levels.
		float *vsw = (selLevel!=PATCH_OBJECT) ? pmesh.GetVSelectionWeights() : NULL;

		if (rd->ivalid.InInterval(t) && (pmesh.numVerts != rd->vnum)) {
			// Shouldn't happen, but does with Loft bug and may with other bugs.
			rd->ivalid.SetEmpty ();
		}

		if (!rd->ivalid.InInterval(t)) {
			int vecBase = pmesh.numVerts;
			rd->SetVNum (pmesh.numVerts + pmesh.numVecs);
			for (i=0; i<rd->vnum; i++) {
				rd->fnum[i]=1;		// For patches, this means it's not a boundary
				rd->nbor[i].ZeroCount();
			}
			rd->sel.ClearAll ();
			for (i=0; i<pmesh.numPatches; i++) {
				Patch &p = pmesh.patches[i];
				int vecLimit = p.type * 2;
				for (j=0; j<p.type; j++) {
					PatchEdge &e = pmesh.edges[p.edge[j]];
					BOOL isBoundary = (e.patches.Count() < 2) ? TRUE : FALSE;
					int theVert = p.v[j];
					int nextVert = p.v[(j+1)%p.type];
					int nextVec = p.vec[j*2] + vecBase;
					int nextVec2 = p.vec[j*2+1] + vecBase;
					int prevEdge = (j+p.type-1)%p.type;
					int prevVec = p.vec[prevEdge*2+1] + vecBase;
					int prevVec2 = p.vec[prevEdge*2] + vecBase;
					int theInterior = p.interior[j] + vecBase;
					// Establish selection bits
					if ((selLevel==PATCH_PATCH) && pmesh.patchSel[i]) {
						rd->sel.Set(theVert);
						rd->sel.Set(nextVec);
						rd->sel.Set(prevVec);
						rd->sel.Set(theInterior);
						}
					else
					if ((selLevel==PATCH_EDGE) && pmesh.edgeSel[p.edge[j]]) {
						rd->sel.Set(e.v1);
						rd->sel.Set(e.vec12 + vecBase);
						rd->sel.Set(e.vec21 + vecBase);
						rd->sel.Set(e.v2);
						}
					else
					if ((selLevel==PATCH_VERTEX) && pmesh.vertSel[theVert]) {
						rd->sel.Set(theVert);
						rd->sel.Set(nextVec);
						rd->sel.Set(prevVec);
						rd->sel.Set(theInterior);
						}

					// Set boundary flags if necessary
					if(isBoundary) {
						rd->fnum[theVert] = 0;
						rd->fnum[nextVec] = 0;
						rd->fnum[nextVec2] = 0;
						rd->fnum[nextVert] = 0;
						}

					// First process the verts
					int work = theVert;
					max = rd->nbor[work].Count();
					// Append the neighboring vectors
					rd->MaybeAppendNeighbor(work, nextVec, max);
					rd->MaybeAppendNeighbor(work, prevVec, max);
					rd->MaybeAppendNeighbor(work, theInterior, max);

					// Now process the edge vectors
					work = nextVec;
					max = rd->nbor[work].Count();
					// Append the neighboring points
					rd->MaybeAppendNeighbor(work, theVert, max);
					rd->MaybeAppendNeighbor(work, theInterior, max);
					rd->MaybeAppendNeighbor(work, prevVec, max);
					rd->MaybeAppendNeighbor(work, nextVec2, max);
					rd->MaybeAppendNeighbor(work, p.interior[(j+1)%p.type] + vecBase, max);

					work = prevVec;
					max = rd->nbor[work].Count();
					// Append the neighboring points
					rd->MaybeAppendNeighbor(work, theVert, max);
					rd->MaybeAppendNeighbor(work, theInterior, max);
					rd->MaybeAppendNeighbor(work, nextVec, max);
					rd->MaybeAppendNeighbor(work, prevVec2, max);
					rd->MaybeAppendNeighbor(work, p.interior[(j+p.type-1)%p.type] + vecBase, max);

					// Now append the interior, if not auto
					if(!p.IsAuto()) {
						work = theInterior;
						max = rd->nbor[work].Count();
						// Append the neighboring points
						rd->MaybeAppendNeighbor(work, p.v[j], max);
						rd->MaybeAppendNeighbor(work, nextVec, max);
						rd->MaybeAppendNeighbor(work, nextVec2, max);
						rd->MaybeAppendNeighbor(work, prevVec, max);
						rd->MaybeAppendNeighbor(work, prevVec2, max);
						for(int k = 1; k < p.type; ++k)
							rd->MaybeAppendNeighbor(work, p.interior[(j+k)%p.type] + vecBase, max);
						}
					}
				}
	// mjm - begin - 4.8.99
			if (selLevel==PATCH_VERTEX) {
				for (int i=0; i<pmesh.numVerts; ++i) {
					if (pmesh.vertSel[i]) rd->sel.Set(i);
				}
			}
			else if (selLevel==PATCH_OBJECT) rd->sel.SetAll();
	// mjm - end
			rd->ivalid  = os->obj->ChannelValidity (t, TOPO_CHAN_NUM);
			rd->ivalid &= os->obj->ChannelValidity (t, SUBSEL_TYPE_CHAN_NUM);
			rd->ivalid &= os->obj->ChannelValidity (t, SELECT_CHAN_NUM);
		}

		Tab<float> vangles;
		if (saddle) vangles.SetCount (rd->vnum);
		Point3 *hold = new Point3[rd->vnum];
		int act;
		for (int k=0; k<iter; k++) {
			for (i=0; i<rd->vnum; i++) hold[i] = patchObj->GetPoint(i);
			if (saddle)
				FindVertexAngles(pmesh, vangles.Addr(0));
			for (i=0; i<rd->vnum; i++) {
	// mjm - begin - 4.8.99
	//			if ((selLevel!=MESH_OBJECT) && (!rd->sel[i])) continue;
				if ( (!rd->sel[i] ) && (!vsw || vsw[i] == 0) ) continue;
	// mjm - end
				if (saddle && (i < pmesh.numVerts) && (vangles[i] <= 2*PI*.99999f)) continue;
				max = rd->nbor[i].Count();
				if (boundary && !rd->fnum[i]) continue;
				if (max<1)
					continue;
				Point3 avg(0.0f, 0.0f, 0.0f);
				for (j=0,act=0; j<max; j++) {
					act++;
					avg += hold[rd->nbor[i][j]];
				}
				if (act<1)
					continue;
	// mjm - begin - 4.8.99
				wtdRelax = (!rd->sel[i]) ? relax * vsw[i] : relax;
				patchObj->SetPoint (i, hold[i]*(1-wtdRelax) + avg*wtdRelax/((float)act));
	//			patchObj->SetPoint (i, hold[i]*(1-relax) + avg*relax/((float)act));
	// mjm - end
			}
		}
		delete [] hold;
		patchObj->patch.computeInteriors();
		patchObj->patch.ApplyConstraints();
	}
#endif // NO_PATCHES
	
	if(!converted) {
		os->obj->SetChannelValidity(GEOM_CHAN_NUM, valid);
	} else {
		// Stuff converted object into the pipeline!
		triObj->SetChannelValidity(TOPO_CHAN_NUM, valid);
		triObj->SetChannelValidity(GEOM_CHAN_NUM, valid);
		triObj->SetChannelValidity(TEXMAP_CHAN_NUM, valid);
		triObj->SetChannelValidity(MTL_CHAN_NUM, valid);
		triObj->SetChannelValidity(SELECT_CHAN_NUM, valid);
		triObj->SetChannelValidity(SUBSEL_TYPE_CHAN_NUM, valid);
		triObj->SetChannelValidity(DISP_ATTRIB_CHAN_NUM, valid);

		os->obj = triObj;
	}
}
Exemplo n.º 28
0
void ExtrudeMod::ModifyObject(TimeValue t, ModContext &mc, ObjectState * os, INode *node) 
	{	
//DebugPrint(_T("Extrude modifying object\n"));

	// Get our personal validity interval...
	Interval valid = GetValidity(t);
	// and intersect it with the channels we use as input (see ChannelsUsed)
	valid &= os->obj->ChannelValidity(t,TOPO_CHAN_NUM);
	valid &= os->obj->ChannelValidity(t,GEOM_CHAN_NUM);
	
	int output;
	pblock->GetValue(PB_OUTPUT, TimeValue(0), output, FOREVER);

	switch (output) {
	case NURBS_OUTPUT:
#ifndef NO_NURBS
		{
		// Here is where all the fun stuff happens -- GenerateExtrudeSurface fills in the EM,
		// then we stuff the EditableSurface into the pipeline.
		ShapeObject *shape = (ShapeObject *)os->obj;
			float amount;

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

		int levels,capStart,capEnd,capType;

		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);

		pblock->GetValue(PB_AMOUNT,t,amount,FOREVER);
		LimitValue(amount, -1000000.0f, 1000000.0f);


		BOOL suspended = FALSE;
		if (theHold.Holding()) {
			theHold.Suspend();
			suspended = TRUE;
		}
		Object *nobj = CreateNURBSExtrudeShape(ip, GetString(IDS_RB_EXTRUDE), t, shape, amount,
								capStart, capEnd, capType, texturing, genMatIds, useShapeIDs);
		if (suspended) {
			theHold.Resume();
		}

        // We only set geom validity because we preserve animation on clone
        // and copying other cahnnels causes problems -- SCM 9/2/97
		nobj->SetChannelValidity(GEOM_CHAN_NUM, valid);

		os->obj = nobj;
		break;}
#endif
#ifndef NO_PATCHES
	case PATCH_OUTPUT: {
		// Here is where all the fun stuff happens -- BuildPatchFromShape fills in the PatchObject's patch mesh,
		// then we stuff the PatchObject into the pipeline.
		PatchObject *pat = new PatchObject;
		BuildPatchFromShape(t, mc, os, pat->patch);

		pat->SetChannelValidity(TOPO_CHAN_NUM, valid);
		pat->SetChannelValidity(GEOM_CHAN_NUM, valid);
		pat->SetChannelValidity(TEXMAP_CHAN_NUM, valid);
		pat->SetChannelValidity(MTL_CHAN_NUM, valid);
		pat->SetChannelValidity(SELECT_CHAN_NUM, valid);
		pat->SetChannelValidity(SUBSEL_TYPE_CHAN_NUM, valid);
		pat->SetChannelValidity(DISP_ATTRIB_CHAN_NUM, valid);

		os->obj = pat;
		break;}
#endif // NO_PATCHES
	case MESH_OUTPUT: {
		// Here is where all the fun stuff happens -- BuildMeshFromShape fills in the TriObject's mesh,
		// then we stuff the TriObj into the pipeline.
		TriObject *tri = CreateNewTriObject();
		BuildMeshFromShape(t, mc, os, tri->GetMesh());

		tri->SetChannelValidity(TOPO_CHAN_NUM, valid);
		tri->SetChannelValidity(GEOM_CHAN_NUM, valid);
		tri->SetChannelValidity(TEXMAP_CHAN_NUM, valid);
		tri->SetChannelValidity(MTL_CHAN_NUM, valid);
		tri->SetChannelValidity(SELECT_CHAN_NUM, valid);
		tri->SetChannelValidity(SUBSEL_TYPE_CHAN_NUM, valid);
		tri->SetChannelValidity(DISP_ATTRIB_CHAN_NUM, valid);

		os->obj = tri;
		break; }
#ifdef XXDESIGN_VER
	case AMSOLID_OUTPUT: {
		//Create an extrusion solid using Facet Modeler
		Object* solid = (Object*)CreateInstance(GEOMOBJECT_CLASS_ID, GENERIC_AMSOLID_CLASS_ID);
		assert(solid);
		if(solid)
		{
			IGeomImp* cacheptr = (IGeomImp*)(solid->GetInterface(I_GEOMIMP));
			assert(cacheptr);
			if(cacheptr)
			{
				bool res = BuildAMSolidFromShape(t, mc, os, cacheptr);
				solid->ReleaseInterface(I_GEOMIMP, cacheptr);
				if(!res)
				{
					valid.SetInstant(t);
//					assert(!cacheptr->isNull());
				}
				for(int i=0; i<NUM_OBJ_CHANS;i++)
					solid->SetChannelValidity(i, valid);
				os->obj = solid;
			}

		}

		break; }
#endif
	}

	os->obj->UnlockObject();
	}
Exemplo n.º 29
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();
	}