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