예제 #1
0
int
APITestUtil::MakeTestCVSurface(NURBSSet &nset, Matrix3 mat, BOOL rigid)
{
	NURBSCVSurface *s = new NURBSCVSurface();
	s->SetRigid(rigid);
	s->SetName(GetString(IDS_CV_SURFACE));
	s->SetNumCVs(4, 4);

	s->SetUOrder(4);
	s->SetVOrder(4);
	s->SetNumUKnots(8);
	s->SetNumVKnots(8);
	for (int k = 0; k < 4; k++) {
		s->SetUKnot(k, 0.0);
		s->SetVKnot(k, 0.0);
		s->SetUKnot(k+4, 1.0);
		s->SetVKnot(k+4, 1.0);
	}

	NURBSControlVertex cv;
	for (int u = 0; u < 4; u++) {
		float up = 100.0f * ((float)u/3.0f);
		for (int v = 0; v < 4; v++) {
			float vp = 100.0f * ((float)v/3.0f);
			cv.SetPosition(0, mat * Point3(-150.0f + up, -100.0f + vp, 0.0f));
			TCHAR name[20];
			_stprintf(name, _T("%s[%d,%d]"), GetString(IDS_CV), u, v);
			cv.SetName(name);
			s->SetCV(u, v, cv);
		}
	}
	return nset.AppendObject(s);
}
예제 #2
0
static void
AddObjectsForBreakTests(NURBSSet &nset, int &c1, int &s1)
{
	NURBSCVCurve *c = new NURBSCVCurve();
	c->SetName(GetString(IDS_BREAK_CURVE));
	c->SetNumCVs(4);

	c->SetOrder(4);
	c->SetNumKnots(8);
	for (int k = 0; k < 4; k++) {
		c->SetKnot(k, 0.0);
		c->SetKnot(k+4, 1.0);
	}

	NURBSControlVertex cv;
	cv.SetPosition(0, Point3(200, 0, 50));
	c->SetCV(0, cv);
	cv.SetPosition(0, Point3(300, 0, 50));
	c->SetCV(1, cv);
	cv.SetPosition(0, Point3(300, -100, 50));
	c->SetCV(2, cv);
	cv.SetPosition(0, Point3(200, -100, 50));
	c->SetCV(3, cv);

	c1 = nset.AppendObject(c);
	NURBSCVSurface *s = new NURBSCVSurface();
	s->SetName(GetString(IDS_BREAK_SURFACE));
	s->SetNumCVs(4, 4);

	s->SetUOrder(4);
	s->SetVOrder(4);
	s->SetNumUKnots(8);
	s->SetNumVKnots(8);
	for (k = 0; k < 4; k++) {
		s->SetUKnot(k, 0.0);
		s->SetVKnot(k, 0.0);
		s->SetUKnot(k+4, 1.0);
		s->SetVKnot(k+4, 1.0);
	}

	for (int u = 0; u < 4; u++) {
		float up = 100.0f * ((float)u/3.0f);
		for (int v = 0; v < 4; v++) {
			float vp = 100.0f * ((float)v/3.0f);
			cv.SetPosition(0, Point3(-150.0f + up, -100.0f + vp, -200.0f));
			s->SetCV(u, v, cv);
		}
	}
	s1 = nset.AppendObject(s);
}
예제 #3
0
파일: prism.cpp 프로젝트: artemeliy/inf4715
Object*
BuildNURBSPrism(float side1, float side2, float side3, float height, int genUVs)
{
	float s13len=side1*side3;
	float theta = (float)acos((side2*side2 - side1*side1 - side3*side3)/(-2.0f*s13len));

	int prism_faces[5][4] = {{0, 1, 2, 2}, // bottom
							{1, 0, 4, 3}, // front
							{2, 1, 5, 4}, // left
							{0, 2, 3, 5}, // right
							{4, 3, 5, 5}};// top
	Point3 prism_verts[6] ={Point3(0.0f, 0.0f, 0.0f),
							Point3(side1,  0.0f, 0.0f),
							Point3(side3*(float)cos(theta), side3*(float)sin(theta), 0.0f),
							Point3(0.0f, 0.0f, height),
							Point3(side1,  0.0f, height),
							Point3(side3*(float)cos(theta), side3*(float)sin(theta), height)};

	NURBSSet nset;

	for (int face = 0; face < 5; face++) {
		Point3 bl = prism_verts[prism_faces[face][0]];
		Point3 br = prism_verts[prism_faces[face][1]];
		Point3 tl = prism_verts[prism_faces[face][2]];
		Point3 tr = prism_verts[prism_faces[face][3]];

		NURBSCVSurface *surf = new NURBSCVSurface();
		nset.AppendObject(surf);
		surf->SetUOrder(4);
		surf->SetVOrder(4);
		surf->SetNumCVs(4, 4);
		surf->SetNumUKnots(8);
		surf->SetNumVKnots(8);

		Point3 top, bot;
		for (int r = 0; r < 4; r++) {
			top = tl + (((float)r/3.0f) * (tr - tl));
			bot = bl + (((float)r/3.0f) * (br - bl));
			for (int c = 0; c < 4; c++) {
				NURBSControlVertex ncv;
				ncv.SetPosition(0, bot + (((float)c/3.0f) * (top - bot)));
				ncv.SetWeight(0, 1.0f);
				surf->SetCV(r, c, ncv);
			}
		}

		for (int k = 0; k < 4; k++) {
			surf->SetUKnot(k, 0.0);
			surf->SetVKnot(k, 0.0);
			surf->SetUKnot(k + 4, 1.0);
			surf->SetVKnot(k + 4, 1.0);
		}

		surf->Renderable(TRUE);
		surf->SetGenerateUVs(genUVs);
		if (height > 0.0f)
			surf->FlipNormals(TRUE);
		else
			surf->FlipNormals(FALSE);

		float sum = side1 + side2 + side3;
		float s1 = side1/sum;
		float s3 = 1.0f - side3/sum;
		switch(face) {
		case 0:
			surf->SetTextureUVs(0, 0, Point2(0.5f, 0.0f));
			surf->SetTextureUVs(0, 1, Point2(0.5f, 0.0f));
			surf->SetTextureUVs(0, 2, Point2(1.0f, 1.0f));
			surf->SetTextureUVs(0, 3, Point2(0.0f, 1.0f));
			break;
		case 1:
			surf->SetTextureUVs(0, 0, Point2(s1, 1.0f));
			surf->SetTextureUVs(0, 1, Point2(0.0f, 1.0f));
			surf->SetTextureUVs(0, 2, Point2(s1, 0.0f));
			surf->SetTextureUVs(0, 3, Point2(0.0f, 0.0f));
			break;
		case 2:
			surf->SetTextureUVs(0, 0, Point2(s3, 1.0f));
			surf->SetTextureUVs(0, 1, Point2(s1, 1.0f));
			surf->SetTextureUVs(0, 2, Point2(s3, 0.0f));
			surf->SetTextureUVs(0, 3, Point2(s1, 0.0f));
			break;
		case 3:
			surf->SetTextureUVs(0, 0, Point2(1.0f, 1.0f));
			surf->SetTextureUVs(0, 1, Point2(s3, 1.0f));
			surf->SetTextureUVs(0, 2, Point2(1.0f, 0.0f));
			surf->SetTextureUVs(0, 3, Point2(s3, 0.0f));
			break;
		case 4:
			surf->SetTextureUVs(0, 0, Point2(0.5f, 1.0f));
			surf->SetTextureUVs(0, 1, Point2(0.5f, 1.0f));
			surf->SetTextureUVs(0, 2, Point2(1.0f, 0.0f));
			surf->SetTextureUVs(0, 3, Point2(0.0f, 0.0f));
			break;
		}

		TCHAR bname[80];
		_stprintf(bname, _T("%s%02d"), GetString(IDS_CT_SURF), face);
		surf->SetName(bname);
	}

#define F(s1, s2, s1r, s1c, s2r, s2c) \
	fuse.mSurf1 = (s1); \
	fuse.mSurf2 = (s2); \
	fuse.mRow1 = (s1r); \
	fuse.mCol1 = (s1c); \
	fuse.mRow2 = (s2r); \
	fuse.mCol2 = (s2c); \
	nset.mSurfFuse.Append(1, &fuse);

	NURBSFuseSurfaceCV fuse;
	// Bottom(0) to Front (1)
	F(0, 1, 3, 0, 0, 0);
	F(0, 1, 2, 0, 1, 0);
	F(0, 1, 1, 0, 2, 0);
	F(0, 1, 0, 0, 3, 0);

	// Bottom(0) to Left (2)
	F(0, 2, 3, 0, 3, 0);
	F(0, 2, 3, 1, 2, 0);
	F(0, 2, 3, 2, 1, 0);
	F(0, 2, 3, 3, 0, 0);

	// Bottom(0) to Right (3)
	F(0, 3, 0, 0, 0, 0);
	F(0, 3, 0, 1, 1, 0);
	F(0, 3, 0, 2, 2, 0);
	F(0, 3, 0, 3, 3, 0);

	// Top(4) to Front (1)
	F(4, 1, 3, 0, 3, 3);
	F(4, 1, 2, 0, 2, 3);
	F(4, 1, 1, 0, 1, 3);
	F(4, 1, 0, 0, 0, 3);

	// Top(4) to Left (2)
	F(4, 2, 0, 0, 3, 3);
	F(4, 2, 0, 1, 2, 3);
	F(4, 2, 0, 2, 1, 3);
	F(4, 2, 0, 3, 0, 3);

	// Top(4) to Right (3)
	F(4, 3, 3, 0, 0, 3);
	F(4, 3, 3, 1, 1, 3);
	F(4, 3, 3, 2, 2, 3);
	F(4, 3, 3, 3, 3, 3);

	// Front(1) to Left (2)
	F(1, 2, 0, 1, 3, 1);
	F(1, 2, 0, 2, 3, 2);

	// Left(2) to Right (3)
	F(2, 3, 0, 1, 3, 1);
	F(2, 3, 0, 2, 3, 2);

	// Right(3) to Front (1)
	F(3, 1, 0, 1, 3, 1);
	F(3, 1, 0, 2, 3, 2);

	// Fuse the triangles together
	for (int i = 1; i < 4; i++) {
		F(0, 0, 0, 3, i, 3);
		F(4, 4, 0, 3, i, 3);
	}

	Matrix3 mat;
	mat.IdentityMatrix();
	Object *obj = CreateNURBSObject(NULL, &nset, mat);
	return obj;
}
예제 #4
0
bool AlembicCurves::Save(double time, bool bLastFrame)
{
    ESS_PROFILE_FUNC();

    //TimeValue ticks = GET_MAX_INTERFACE()->GetTime();
    TimeValue ticks = GetTimeValueFromFrame(time);
	Object *obj = mMaxNode->EvalWorldState(ticks).obj;
	if(mNumSamples == 0){
		bForever = CheckIfObjIsValidForever(obj, ticks);
	}
	else{
		bool bNewForever = CheckIfObjIsValidForever(obj, ticks);
		if(bForever && bNewForever != bForever){
			ESS_LOG_INFO( "bForever has changed" );
		}
	}

	SaveMetaData(mMaxNode, this);

    // check if the spline is animated
    if(mNumSamples > 0) 
    {
        if(bForever)
        {
            return true;
        }
    }

    AbcG::OCurvesSchema::Sample curvesSample;

	std::vector<AbcA::int32_t> nbVertices;
    std::vector<Point3> vertices;
    std::vector<float> knotVector;
    std::vector<Abc::uint16_t> orders;

    if(obj->ClassID() == EDITABLE_SURF_CLASS_ID){

       NURBSSet nurbsSet;   
       BOOL success = GetNURBSSet(obj, ticks, nurbsSet, TRUE);   

       AbcG::CurvePeriodicity cPeriod = AbcG::kNonPeriodic;
       AbcG::CurveType cType = AbcG::kCubic;
       AbcG::BasisType cBasis = AbcG::kNoBasis;

       int n = nurbsSet.GetNumObjects();
       for(int i=0; i<n; i++){
          NURBSObject* pObject = nurbsSet.GetNURBSObject((int)i);

          //NURBSType type = pObject->GetType();
          if(!pObject){
             continue;
          }

          if( pObject->GetKind() == kNURBSCurve ){
             NURBSCurve* pNurbsCurve = (NURBSCurve*)pObject;

             int degree;
             int numCVs;
             NURBSCVTab cvs;
			 int numKnots;
		     NURBSKnotTab knots;
             pNurbsCurve->GetNURBSData(ticks, degree, numCVs, cvs, numKnots, knots);

             orders.push_back(degree+1);

             const int cvsCount = cvs.Count();
             const int knotCount = knots.Count();

             for(int j=0; j<cvs.Count(); j++){
                NURBSControlVertex cv = cvs[j];
                double x, y, z;
                cv.GetPosition(ticks, x, y, z);
                vertices.push_back( Point3((float)x, (float)y, (float)z) );
             }

             nbVertices.push_back(cvsCount);

             //skip the first and last entry because Maya and XSI use this format
             for(int j=1; j<knots.Count()-1; j++){
                knotVector.push_back((float)knots[j]);
             }

             if(i == 0){
                if(pNurbsCurve->IsClosed()){
                   cPeriod = AbcG::kPeriodic;
                }  
             }
             else{
                if(pNurbsCurve->IsClosed()){
                   if(cPeriod != AbcG::kPeriodic){
                      ESS_LOG_WARNING("Mixed curve wrap types not supported.");
                   }
                }
                else{
                   if(cPeriod != AbcG::kNonPeriodic){
                      ESS_LOG_WARNING("Mixed curve wrap types not supported.");
                   }
                }
             }

          }
          
       }
       

       curvesSample.setType(cType);
       curvesSample.setWrap(cPeriod);
       curvesSample.setBasis(cBasis);
    }
    else
    {
          BezierShape beziershape;
          PolyShape polyShape;
          bool bBezier = false;

          // Get a pointer to the spline shpae
          ShapeObject *pShapeObject = NULL;
          if (obj->IsShapeObject())
          {
              pShapeObject = reinterpret_cast<ShapeObject *>(obj);
          }
          else
          {
              return false;
          }

          // Determine if we are a bezier shape
          if (pShapeObject->CanMakeBezier())
          {
              pShapeObject->MakeBezier(ticks, beziershape);
              bBezier = true;
          }
          else
          {
              pShapeObject->MakePolyShape(ticks, polyShape);
              bBezier = false;
          }

          // Get the control points

          //std::vector<Point3> inTangents;
	      //std::vector<Point3> outTangents;
          if (bBezier)
          {
              int oldVerticesCount = (int)vertices.size();
              for (int i = 0; i < beziershape.SplineCount(); i += 1)
              {
                  Spline3D *pSpline = beziershape.GetSpline(i);
                  int knots = pSpline->KnotCount();
                  for(int ix = 0; ix < knots; ++ix) 
                  {
                      Point3 in = pSpline->GetInVec(ix);
                      Point3 p = pSpline->GetKnotPoint(ix);
                      Point3 out = pSpline->GetOutVec(ix);

                      vertices.push_back( p );
				      //inTangents.push_back( in );
				      //outTangents.push_back( out );
                  }

                  int nNumVerticesAdded = (int)vertices.size() - oldVerticesCount;
                  nbVertices.push_back( nNumVerticesAdded );
                  oldVerticesCount = (int)vertices.size();
              }
          }
          else
          {
              for (int i = 0; i < polyShape.numLines; i += 1)
              {
                  PolyLine &refLine = polyShape.lines[i];
                  nbVertices.push_back(refLine.numPts);
                  for (int j = 0; j < refLine.numPts; j += 1)
                  {
                      Point3 p = refLine.pts[j].p;
                      vertices.push_back(p);
                  }
              }
          }

          // set the type + wrapping
	      curvesSample.setType(bBezier ? AbcG::kCubic : AbcG::kLinear);
          curvesSample.setWrap(pShapeObject->CurveClosed(ticks, 0) ? AbcG::kPeriodic : AbcG::kNonPeriodic);
          curvesSample.setBasis(AbcG::kNoBasis);
    }

    if(nbVertices.size() == 0 || vertices.size() == 0){
       ESS_LOG_WARNING("No curve data to export.");
       return false;
    }
 

    const int vertCount = (int)vertices.size();

    // prepare the bounding box
    Abc::Box3d bbox;

    // allocate the points and normals
    std::vector<Abc::V3f> posVec(vertCount);
    Matrix3 wm = mMaxNode->GetObjTMAfterWSM(ticks);

    for(int i=0;i<vertCount;i++)
    {
        posVec[i] = ConvertMaxPointToAlembicPoint(vertices[i] );
        bbox.extendBy(posVec[i]);

        // Set the archive bounding box
        if (mJob)
        {
            Point3 worldMaxPoint = wm * vertices[i];
            Abc::V3f alembicWorldPoint = ConvertMaxPointToAlembicPoint(worldMaxPoint);
            mJob->GetArchiveBBox().extendBy(alembicWorldPoint);
        }
    }

    if(knotVector.size() > 0 && orders.size() > 0){
       if(!mKnotVectorProperty.valid()){
          mKnotVectorProperty = Abc::OFloatArrayProperty(mCurvesSchema.getArbGeomParams(), ".knot_vector", mCurvesSchema.getMetaData(), mJob->GetAnimatedTs() );
       }
       mKnotVectorProperty.set(Abc::FloatArraySample(knotVector));

       if(!mOrdersProperty.valid()){
          mOrdersProperty = Abc::OUInt16ArrayProperty(mCurvesSchema.getArbGeomParams(), ".orders", mCurvesSchema.getMetaData(), mJob->GetAnimatedTs() );
       }
       mOrdersProperty.set(Abc::UInt16ArraySample(orders));
    }

    // store the bbox
    curvesSample.setSelfBounds(bbox);
	mCurvesSchema.getChildBoundsProperty().set(bbox);

 
    Abc::Int32ArraySample nbVerticesSample(&nbVertices.front(),nbVertices.size());
    curvesSample.setCurvesNumVertices(nbVerticesSample);


 
    // allocate for the points and normals
    Abc::P3fArraySample posSample(&posVec.front(),posVec.size());
	curvesSample.setPositions(posSample);


    mCurvesSchema.set(curvesSample);

   mNumSamples++;

   return true;
}
예제 #5
0
Object*
BuildNURBSPyramid(float width, float depth, float height, int genUVs)
{
	int pyramid_faces[5][4] = { {0, 1, 2, 3}, // bottom
							{2, 3, 4, 4}, // back
							{1, 0, 4, 4}, // front
							{3, 1, 4, 4}, // left
							{0, 2, 4, 4}};// right
	Point3 pyramid_verts[5] = { Point3(-0.5, -0.5, 0.0),
							Point3( 0.5, -0.5, 0.0),
							Point3(-0.5,  0.5, 0.0),
							Point3( 0.5,  0.5, 0.0),
							Point3( 0.0,  0.0, 1.0)};

	NURBSSet nset;

	for (int face = 0; face < 5; face++) {
		Point3 bl = pyramid_verts[pyramid_faces[face][0]];
		Point3 br = pyramid_verts[pyramid_faces[face][1]];
		Point3 tl = pyramid_verts[pyramid_faces[face][2]];
		Point3 tr = pyramid_verts[pyramid_faces[face][3]];

		Matrix3 size;
		size.IdentityMatrix();
		Point3 lwh(width, depth, height);
		size.Scale(lwh);

		bl = bl * size;
		br = br * size;
		tl = tl * size;
		tr = tr * size;

		NURBSCVSurface *surf = new NURBSCVSurface();
		nset.AppendObject(surf);
		surf->SetUOrder(4);
		surf->SetVOrder(4);
		surf->SetNumCVs(4, 4);
		surf->SetNumUKnots(8);
		surf->SetNumVKnots(8);

		Point3 top, bot;
		for (int r = 0; r < 4; r++) {
			top = tl + (((float)r/3.0f) * (tr - tl));
			bot = bl + (((float)r/3.0f) * (br - bl));
			for (int c = 0; c < 4; c++) {
				NURBSControlVertex ncv;
				ncv.SetPosition(0, bot + (((float)c/3.0f) * (top - bot)));
				ncv.SetWeight(0, 1.0f);
				surf->SetCV(r, c, ncv);
			}
		}

		for (int k = 0; k < 4; k++) {
			surf->SetUKnot(k, 0.0);
			surf->SetVKnot(k, 0.0);
			surf->SetUKnot(k + 4, 1.0);
			surf->SetVKnot(k + 4, 1.0);
		}

		surf->Renderable(TRUE);
		surf->SetGenerateUVs(genUVs);
		if (height > 0.0f)
			surf->FlipNormals(TRUE);
		else
			surf->FlipNormals(FALSE);

		switch(face) {
		case 0: // bottom
			surf->SetTextureUVs(0, 0, Point2(1.0f, 0.0f));
			surf->SetTextureUVs(0, 1, Point2(0.0f, 0.0f));
			surf->SetTextureUVs(0, 2, Point2(1.0f, 1.0f));
			surf->SetTextureUVs(0, 3, Point2(0.0f, 1.0f));
			break;
		default: // sides
			surf->SetTextureUVs(0, 0, Point2(0.5f, 1.0f));
			surf->SetTextureUVs(0, 1, Point2(0.5f, 1.0f));
			surf->SetTextureUVs(0, 2, Point2(0.0f, 0.0f));
			surf->SetTextureUVs(0, 3, Point2(1.0f, 0.0f));
			break;
		}

		TCHAR bname[80];
		_stprintf(bname, _T("%s%02d"), GetString(IDS_CT_SURF), face);
		surf->SetName(bname);
	}

#define F(s1, s2, s1r, s1c, s2r, s2c) \
	fuse.mSurf1 = (s1); \
	fuse.mSurf2 = (s2); \
	fuse.mRow1 = (s1r); \
	fuse.mCol1 = (s1c); \
	fuse.mRow2 = (s2r); \
	fuse.mCol2 = (s2c); \
	nset.mSurfFuse.Append(1, &fuse);

	NURBSFuseSurfaceCV fuse;
	// Fuse the degenerate peaks
	for (int i = 1; i < 5; i++) {
		for (int j = 1; j < 4; j++) {
			F(i, i, 0, 3, j, 3);
		}
	}

	// Fuse the peaks together
	F(1, 2, 0, 3, 0, 3);
	F(1, 3, 0, 3, 0, 3);
	F(1, 4, 0, 3, 0, 3);

	// Bottom(0) to Back (1)
	F(0, 1, 3, 3, 3, 0);
	F(0, 1, 2, 3, 2, 0);
	F(0, 1, 1, 3, 1, 0);
	F(0, 1, 0, 3, 0, 0);

	// Bottom(0) to Front (2)
	F(0, 2, 0, 0, 3, 0);
	F(0, 2, 1, 0, 2, 0);
	F(0, 2, 2, 0, 1, 0);
	F(0, 2, 3, 0, 0, 0);

	// Bottom(0) to Left (3)
	F(0, 3, 3, 0, 3, 0);
	F(0, 3, 3, 1, 2, 0);
	F(0, 3, 3, 2, 1, 0);
	F(0, 3, 3, 3, 0, 0);

	// Bottom(0) to Right (4)
	F(0, 4, 0, 0, 0, 0);
	F(0, 4, 0, 1, 1, 0);
	F(0, 4, 0, 2, 2, 0);
	F(0, 4, 0, 3, 3, 0);

	// Front (2)  to Right (4)
	F(2, 4, 3, 1, 0, 1);
	F(2, 4, 3, 2, 0, 2);

	// Right (4) to Back (1)
	F(4, 1, 3, 1, 0, 1);
	F(4, 1, 3, 2, 0, 2);

	// Back (1) to Left (3)
	F(1, 3, 3, 1, 0, 1);
	F(1, 3, 3, 2, 0, 2);

	// Left (3) to Front (2)
	F(3, 2, 3, 1, 0, 1);
	F(3, 2, 3, 2, 0, 2);

	Matrix3 mat;
	mat.IdentityMatrix();
	Object *obj = CreateNURBSObject(NULL, &nset, mat);
	return obj;
}