END_TEST START_TEST (test_ParametricObject_output) { const char *expected = "<parametricObject id=\"i\" polygonType=\"triangle\" domainType=\"p\">\n" " <polygonObject pointIndexLength=\"3\">1 2 3 </polygonObject>\n" "</parametricObject>"; PolygonObject *obj = new PolygonObject(GNS); int points [] = {1,2,3}; obj->setPointIndex(points, 3); G->setId("i"); G->setPolygonType("triangle"); G->setDomainType("p"); G->setPolygonObject(obj); S = G->toSBML(); fail_unless( equals(expected, S) ); delete obj; }
/*===========================================================================*/ void PolygonObject::shallowCopy( const PolygonObject& object ) { BaseClass::shallowCopy( object ); m_polygon_type = object.polygonType(); m_color_type = object.colorType(); m_normal_type = object.normalType(); m_connections = object.connections(); m_opacities = object.opacities(); }
//This method gets called for every brush dab for every symmetrical brush. Bool SculptSelectionBrush::MovePointsFunc(BrushDabData* dab) { //Get the PolygonObject that this brush dab is touching. //If its a sculpt object (ie it has a SculptTag) then this object is a high res object and not the base object so we can't change selections on it. if (dab->IsSculptObject()) return false; PolygonObject* pPoly = dab->GetPolygonObject(); //Get the polygon selection for the PolygonObject. BaseSelect* pSelect = pPoly->GetPolygonS(); //Loop over every polygon that the brush dab has touched and add the index for the polygon to the selection. Int32 polyCount = dab->GetPolyCount(); const BrushPolyData* pPolyData = dab->GetPolyData(); for (Int32 a = 0; a < polyCount; a++) { pSelect->Select(pPolyData[a].polyIndex); } pPoly->SetDirty(DIRTYFLAGS_SELECT); return true; }
//This method does all the work for the brush. Every time the mouse moves this will be called for each brush on the surface of the model. Bool ExampleSculptGrabBrush::MovePointsFunc(BrushDabData* dab) { PolygonObject* polyObj = dab->GetPolygonObject(); if (!polyObj) return false; Int32 a; //Get the world matrix for the model so that we can turn local coordinates into world coordinates. Matrix mat = polyObj->GetMg(); //Get the location of the hitpoint on the model in world coordinates Vector hitPointWorld = mat * dab->GetHitPoint(); //Zero out the offset since its no longer required mat.off = Vector(0, 0, 0); const BaseContainer* pData = dab->GetData(); //Get our custom direction value that we added to our .res file. Int32 dirMode = pData->GetInt32(MDATA_TOOLSCULPTGRABBRUSH_DIRMODE); //Find the distance the mouse has moved in world coordinates by getting the world position of the mouse and subtracting the current grab brush world coordinate Vector moveAmnt = (dab->GetMousePos3D() - hitPointWorld); //Transform this distance into a vector that is in the local coordinates of the model. moveAmnt = ~mat * moveAmnt; Vector normal = dab->GetNormal(); switch (dirMode) { case MDATA_TOOLSCULPTGRABBRUSH_DIRMODE_NORMAL: { //If we are moving the point in the direction of its normal then use the length of the distance vector to scale the normal. moveAmnt = normal * moveAmnt.GetLength(); //Adjust the direction of the vector depending on if its moving above the surface or below it. Float dot = Dot(normal, moveAmnt); if (dot < 0) moveAmnt *= -1; break; } case MDATA_TOOLSCULPTGRABBRUSH_DIRMODE_MOUSEDIR: default: //Nothing to do here since moveAmnt is already correct. break; } //Get the original points on the surface of the object. These points are the state of the object when the //user first clicks on the model to do a mouse stroke. This allows you to compare where the points are during //a stroke, since you have moved them, when the original positions. const Vector32* pOriginalPoints = dab->GetOriginalPoints(); Int32 pointCount = dab->GetPointCount(); const Vector* pPoints = dab->GetPoints(); const BrushPointData* pPointData = dab->GetPointData(); //If any of the symmetry settings have been enabled, and this is a symmetry stroke instance, then this will return true. Bool mirror = dab->IsMirroredDab(); //Loop over every point on the dab and move them by the moveAmnt. for (a = 0; a < pointCount; ++a) { Int32 pointIndex = pPointData[a].pointIndex; //Get the falloff value for this point. This value will take into account the current stencil, stamp settings and the falloff curve to create this value. Float fallOff = dab->GetBrushFalloff(a); //Get the original location for this point Vector original = (Vector64)pOriginalPoints[pointIndex]; //Get the vector of the point we are going to change. const Vector& currentPoint = pPoints[pointIndex]; //If the user has any of the symmetry settings enabled and this is one of the symmetrical brush instance then mirror will be True. //We can check to see if another brush instance has already touched this point and moved it by calling the IsPointModified method. //If a point has been touched then that means it has already been moved by a certain vector by that brush instance. //This happens when the brushes overlap the same area of the model, which can easily happen if you have a large brush size and are using symmetry. //So we just offset it by another vector and do not worry about the original location of the point. if (mirror && dab->IsPointModified(pointIndex)) { //Adjust the offset by the new amount. dab->OffsetPoint(pointIndex, moveAmnt * fallOff); } else { //If there is no symmetry or the point hasn't been touched then we can just set the position of the point normally. //First determine the offset vector by using the original location of the point and adding on the new point after it has been adjusted by the falloff value. Vector newPosOffset = original + moveAmnt * fallOff; //A new offset is calculated by using this new point and its current position. Vector offset = newPosOffset - currentPoint; //Offset the point to place it in the correct location. dab->OffsetPoint(pointIndex, offset); } } //Ensure that all the points for the dab are marked as dirty. This is required to ensure that they all update even if they were not directly //touched by this brush instance. Marking all points as dirty ensures that the normals for all points are updated. This is only required //for grab brushes when multiple brush instances are touching the same points. dab->DirtyAllPoints(SCULPTBRUSHDATATYPE_POINT); return true; }
Bool ApplinkImporter::createObjects() { BaseDocument* doc = GetActiveDocument(); Int32 vertCnt = 0; const Matrix tM(Vector(0.0f, 0.0f, 0.0f), Vector(1.0f, 0.0f, 0.0f), Vector(0.0f, 1.0f, 0.0f), Vector(0.0f, 0.0f, -1.0f)); StatusSetText("Create objects..."); for(unsigned int i = 0; i < groups.size(); i++) { Vector *vadr = 0;// vertex adress CPolygon *padr = 0;// polygon adress Group gr = this->groups[i]; if(this->pSet.impReplace) { BaseObject* bo = doc->SearchObject(gr.groupName); if(bo) { BaseObject::Free(bo); } } PolygonObject* pObj = PolygonObject::Alloc(gr.numGVertices, gr.numGFaces); if (!pObj){ return false;} pObj->SetName(this->groups[i].groupName); //GePrint("Name group: " + pObj->GetName()); GePrint("V count: " + String::IntToString((Int32)gr.numGVertices)); GePrint("Poly count: " + String::IntToString((Int32)gr.numGFaces)); vadr = pObj->GetPointW(); padr = pObj->GetPolygonW(); for (int p = 0; p < gr.numGFaces; p++) { padr[p] = CPolygon(gr.faces[p].vp[0] - vertCnt, gr.faces[p].vp[1] - vertCnt, gr.faces[p].vp[2] - vertCnt, gr.faces[p].vp[3] - vertCnt); //GePrint("poly " + LongToString(p) + ": " + LongToString(padr[p].a) + ", " + LongToString(padr[p].b) + ", " + LongToString(padr[p].c) + ", " + LongToString(padr[p].d)); } for (int v = 0; v < gr.numGVertices; v++) { vadr[v] = tM * this->verticies[v + vertCnt] ; //GePrint("vert " + LongToString(v) + ": " + LongToString(vadr[v].x) + ", " + LongToString(vadr[v].y) + ", " + LongToString(vadr[v].z)); } //// import UV if(ApplinkImporter::pSet.impUV && gr.numGTVertices > 0) { UVWStruct us; UVWTag* uvwtag = nullptr; uvwtag = UVWTag::Alloc(gr.numGFaces); if(!uvwtag) return false; for (Int32 p = 0; p < gr.numGFaces; p++) { us = UVWStruct(this->uvw[gr.faces[p].vt[0]], this->uvw[gr.faces[p].vt[1]], this->uvw[gr.faces[p].vt[2]], this->uvw[gr.faces[p].vt[3]]); void *dataptr = uvwtag->GetDataAddressW(); uvwtag->Set(dataptr, p, us); } pObj->InsertTag(uvwtag, NULL); uvwtag->Message(MSG_UPDATE); } ////// insert phongTag if (!pObj->MakeTag(Tphong)) GePrint("Error on inserting phongTag. Object: " + pObj->GetName()); /////add materials, textures and poly clusters if(this->pSet.impMat) { String selTagName = ""; if(this->matArray.size() == 1) { this->InsertTextureTag(pObj, this->matArray[0].Name, selTagName); } else if(this->matArray.size() > 1) { this->InsertTextureTag(pObj, this->matArray[0].Name, selTagName); CPolygon ps; SelectionTag* polyTag = NULL; for (Int32 c = 1; c < this->matArray.size(); c++) { polyTag = SelectionTag::Alloc(Tpolygonselection); if(!polyTag) return false; selTagName = "Selection " + String::IntToString(c); polyTag->SetName(selTagName); BaseSelect* sel = polyTag->GetBaseSelect(); for (Int32 p = 0; p < gr.numGFaces; p++) { if(gr.polyMatIdx[p] == c) { sel->Select(p); } } pObj->InsertTag(polyTag, this->GetLastTag(pObj)); polyTag->Message(MSG_UPDATE); this->InsertTextureTag(pObj, this->matArray[c].Name, selTagName); } } } doc->InsertObject(pObj, NULL, NULL); pObj->Message(MSG_UPDATE); ModelingCommandData md; md.doc = doc; md.op = pObj; if(!SendModelingCommand(MCOMMAND_REVERSENORMALS, md)) return false; pObj = 0; vertCnt += gr.numGVertices; } return true; }
void writeSpatialSBML() { /* // SBMLNamespaces of SBML Level 3 Version 1 with Spatial Version 1 SBMLNamespaces sbmlns(3,1,"spatial",1); // SpatialPkgNamespaces spatialns(3,1,1); // add Required Elements package namespace sbmlns.addPkgNamespace("req", 1); */ // SBMLNamespaces of SBML Level 3 Version 1 with 'req' Version 1 // then add 'spatial' package namespace. RequiredElementsPkgNamespaces sbmlns(3,1,1); sbmlns.addPkgNamespace("spatial",1); // create the L3V1 document with spatial package SBMLDocument document(&sbmlns); // set 'required' attribute on document for 'spatial' and 'req' packages to 'T'?? SBMLDocumentPlugin* dplugin; dplugin = static_cast<SBMLDocumentPlugin*>(document.getPlugin("spatial")); dplugin->setRequired(true); dplugin = static_cast<SBMLDocumentPlugin*>(document.getPlugin("req")); dplugin->setRequired(true); // create the Model Model *model = document.createModel(); model-> setId("trial_spatial"); model-> setName("trial_spatial"); // create the Compartments Compartment* compartment = model->createCompartment(); compartment->setId("cytosol"); compartment->setConstant(true); // create the Species Species* species1 = model->createSpecies(); species1->setId("ATPc"); species1->setCompartment("cytosol"); species1->setInitialConcentration(1.0); species1->setHasOnlySubstanceUnits(false); species1->setBoundaryCondition(false); species1->setConstant(false); // spatial package extension to species. // required elements package extention to parameter RequiredElementsSBasePlugin* reqplugin; reqplugin = static_cast<RequiredElementsSBasePlugin*>(species1->getPlugin("req")); reqplugin->setMathOverridden("spatial"); reqplugin->setCoreHasAlternateMath(true); SpatialSpeciesRxnPlugin* srplugin; srplugin = static_cast<SpatialSpeciesRxnPlugin*>(species1->getPlugin("spatial")); srplugin->setIsSpatial(true); // add parameter for diff coeff of species1 Parameter* paramSp = model->createParameter(); paramSp->setId(species1->getId()+"_dc"); paramSp->setValue(1.0); // required elements package extention to parameter reqplugin = static_cast<RequiredElementsSBasePlugin*>(paramSp->getPlugin("req")); reqplugin->setMathOverridden("spatial"); reqplugin->setCoreHasAlternateMath(true); // spatial package extension to parameter. SpatialParameterPlugin* pplugin; pplugin = static_cast<SpatialParameterPlugin*>(paramSp->getPlugin("spatial")); DiffusionCoefficient* diffCoeff = pplugin->getDiffusionCoefficient(); diffCoeff->setVariable(species1->getId()); diffCoeff->setCoordinateIndex(0); // add parameter for adv coeff of species1 paramSp = model->createParameter(); paramSp->setId(species1->getId()+"_ac"); paramSp->setValue(1.5); // required elements package extention to parameter reqplugin = static_cast<RequiredElementsSBasePlugin*>(paramSp->getPlugin("req")); reqplugin->setMathOverridden("spatial"); reqplugin->setCoreHasAlternateMath(true); // spatial package extension to parameter. pplugin = static_cast<SpatialParameterPlugin*>(paramSp->getPlugin("spatial")); AdvectionCoefficient* advCoeff = pplugin->getAdvectionCoefficient(); advCoeff->setVariable(species1->getId()); advCoeff->setCoordinateIndex(0); // add parameter for boundary condition of species1 paramSp = model->createParameter(); paramSp->setId(species1->getId()+"_bc"); paramSp->setValue(2.0); // required elements package extention to parameter reqplugin = static_cast<RequiredElementsSBasePlugin*>(paramSp->getPlugin("req")); reqplugin->setMathOverridden("spatial"); reqplugin->setCoreHasAlternateMath(true); // spatial package extension to parameter. pplugin = static_cast<SpatialParameterPlugin*>(paramSp->getPlugin("spatial")); BoundaryCondition* boundCon = pplugin->getBoundaryCondition(); boundCon->setVariable(species1->getId()); boundCon->setType("value"); boundCon->setCoordinateBoundary("Xmin"); Species* species2 = model->createSpecies(); species2->setId("ADPc"); species2->setCompartment("cytosol"); species2->setInitialConcentration(1); species2->setHasOnlySubstanceUnits(false); species2->setBoundaryCondition(false); species2->setConstant(false); srplugin = static_cast<SpatialSpeciesRxnPlugin*>(species2->getPlugin("spatial")); srplugin->setIsSpatial(true); /* // create a parameter Parameter* param = model->createParameter(); param->setId("k_1"); param->setValue(0.24); param->setConstant(true); // create an assignment rule AssignmentRule* assignRule = model->createAssignmentRule(); assignRule->setVariable(species1->getId()); assignRule->setFormula("species2+k_1"); */ /* reqplugin = static_cast<RequiredElementsSBasePlugin*>(assignRule->getPlugin("req")); reqplugin->setMathOverridden("spatial"); reqplugin->setCoreHasAlternateMath(false); */ Reaction* reaction = model->createReaction(); reaction->setId("rxn1"); reaction->setReversible(false); reaction->setFast(false); reaction->setCompartment("cytosol"); srplugin = static_cast<SpatialSpeciesRxnPlugin*>(reaction->getPlugin("spatial")); srplugin->setIsLocal(true); // // Get a SpatialModelPlugin object plugged in the model object. // // The type of the returned value of SBase::getPlugin() function is // SBasePlugin*, and thus the value needs to be casted for the // corresponding derived class. // SpatialModelPlugin* mplugin; mplugin = static_cast<SpatialModelPlugin*>(model->getPlugin("spatial")); // // Creates a geometry object via SpatialModelPlugin object. // Geometry* geometry = mplugin->getGeometry(); geometry->setCoordinateSystem("XYZ"); CoordinateComponent* coordX = geometry->createCoordinateComponent(); coordX->setSpatialId("coordComp1"); coordX->setComponentType("cartesian"); coordX->setSbmlUnit("umeter"); coordX->setIndex(1); BoundaryMin* minX = coordX->createBoundaryMin(); minX->setSpatialId("Xmin"); minX->setValue(0.0); BoundaryMax* maxX = coordX->createBoundaryMax(); maxX->setSpatialId("Xmax"); maxX->setValue(10.0); Parameter* paramX = model->createParameter(); paramX->setId("x"); paramX->setValue(8.0); // required elements package extention to parameter // RequiredElementsSBasePlugin* reqplugin; reqplugin = static_cast<RequiredElementsSBasePlugin*>(paramX->getPlugin("req")); reqplugin->setMathOverridden("spatial"); reqplugin->setCoreHasAlternateMath(true); // spatial package extension to parameter. // SpatialParameterPlugin* pplugin; pplugin = static_cast<SpatialParameterPlugin*>(paramX->getPlugin("spatial")); SpatialSymbolReference* spSymRef = pplugin->getSpatialSymbolReference(); spSymRef->setSpatialId(coordX->getSpatialId()); spSymRef->setType(coordX->getElementName()); DomainType* domainType = geometry->createDomainType(); domainType->setSpatialId("dtype1"); domainType->setSpatialDimensions(3); // Spatial package extension to compartment (mapping compartment with domainType) // required elements package extention to compartment reqplugin = static_cast<RequiredElementsSBasePlugin*>(compartment->getPlugin("req")); reqplugin->setMathOverridden("spatial"); reqplugin->setCoreHasAlternateMath(true); SpatialCompartmentPlugin* cplugin; cplugin = static_cast<SpatialCompartmentPlugin*>(compartment->getPlugin("spatial")); CompartmentMapping* compMapping = cplugin->getCompartmentMapping(); compMapping->setSpatialId("compMap1"); compMapping->setCompartment(compartment->getId()); compMapping->setDomainType(domainType->getSpatialId()); compMapping->setUnitSize(1.0); Domain* domain = geometry->createDomain(); domain->setSpatialId("domain1"); domain->setDomainType("dtype1"); domain->setImplicit(false); domain->setShapeId("circle"); InteriorPoint* internalPt1 = domain->createInteriorPoint(); internalPt1->setCoord1(1.0); domain = geometry->createDomain(); domain->setSpatialId("domain2"); domain->setDomainType("dtype1"); domain->setImplicit(false); domain->setShapeId("square"); InteriorPoint* internalPt2 = domain->createInteriorPoint(); internalPt2->setCoord1(5.0); AdjacentDomains* adjDomain = geometry->createAdjacentDomains(); adjDomain->setSpatialId("adjDomain1"); adjDomain->setDomain1("domain1"); adjDomain->setDomain2("domain2"); AnalyticGeometry* analyticGeom = geometry->createAnalyticGeometry(); analyticGeom->setSpatialId("analyticGeom1"); AnalyticVolume* analyticVol = analyticGeom->createAnalyticVolume(); analyticVol->setSpatialId("analyticVol1"); analyticVol->setDomainType(domainType->getSpatialId()); analyticVol->setFunctionType("squareFn"); analyticVol->setOrdinal(1); const char* mathMLStr = "<math xmlns=\"http://www.w3.org/1998/Math/MathML\"><apply xmlns=\"\"><plus /><apply><times /><ci>x</ci><ci>x</ci></apply><apply><minus /><cn>1.0</cn></apply></apply></math>"; ASTNode* mathNode = readMathMLFromString(mathMLStr); analyticVol->setMath(mathNode); SampledFieldGeometry* sfg = geometry->createSampledFieldGeometry(); sfg->setSpatialId("sampledFieldGeom1"); SampledField* sampledField = sfg->createSampledField(); sampledField->setSpatialId("sampledField1"); sampledField->setNumSamples1(4); sampledField->setNumSamples2(4); sampledField->setNumSamples3(2); sampledField->setDataType("double"); sampledField->setInterpolationType("linear"); sampledField->setEncoding("encoding1"); //int samples[5] = {1, 2, 3, 4, 5}; int samples[32] = { // z=0 0,0,0,0, 0,1,1,0, 0,1,1,0, 0,0,0,0, // z=1 0,0,0,0, 0,1,1,0, 0,1,1,0, 0,0,0,0 }; ImageData* id = sampledField->createImageData(); id->setDataType("compressed"); id->setSamples(samples, 32); SampledVolume* sampledVol = sfg->createSampledVolume(); sampledVol->setSpatialId("sv_1"); sampledVol->setDomainType(domainType->getSpatialId()); sampledVol->setSampledValue(128.0); sampledVol->setMinValue(0.0); sampledVol->setMaxValue(255.0); ParametricGeometry* pg = geometry->createParametricGeometry(); pg->setSpatialId("parametricGeom1"); ParametricObject* paramObj = pg->createParametricObject(); paramObj->setSpatialId("po_1"); paramObj->setDomain(domain->getSpatialId()); paramObj->setPolygonType("hexagon"); int ptIndices[5] = {1, 2, 3, 4, 5}; PolygonObject* po = paramObj->createPolygonObject(); po->setPointIndices(ptIndices, 5); SpatialPoint* spPt = pg->createSpatialPoint(); spPt->setSpatialId("sp_1"); spPt->setDomain(domain->getSpatialId()); spPt->setCoord1(1); spPt->setCoord2(2); spPt->setCoord3(3); CSGeometry* csg = geometry->createCSGeometry(); csg->setSpatialId("csGeom1"); CSGObject* csgObj = csg->createCSGObject(); csgObj->setSpatialId("csg_csgo_1"); csgObj->setDomainType(domainType->getSpatialId()); csgObj->setOrdinal(1); CSGScale* scale = csgObj->createCSGScale(); scale->setScaleX(2.0); scale->setScaleY(3.0); scale->setScaleZ(4.0); CSGPrimitive* prim1 = scale->createCSGPrimitive(); prim1->setPrimitiveType("SOLID_SPHERE"); csgObj = csg->createCSGObject(); csgObj->setSpatialId("csg_csgo_2"); csgObj->setDomainType(domainType->getSpatialId()); CSGSetOperator* setUnion = csgObj->createCSGSetOperator(); setUnion->setOperationType("UNION"); /* CSGPrimitive* prim = setUnion->createCSGPrimitive(); prim->setPrimitiveType("SOLID_SPHERE"); CSGPrimitive* prim2 = setUnion->createCSGPrimitive(); prim2->setPrimitiveType("SOLID_CONE"); */ CSGPrimitive* prim2 = new CSGPrimitive(3,1,1); prim2->setSpatialId("cone0"); prim2->setPrimitiveType("SOLID_CONE"); CSGTranslation* translatedCone = new CSGTranslation(3,1,1); translatedCone->setSpatialId("translation0"); translatedCone->setTranslateX(2.0); translatedCone->setTranslateY(2.0); translatedCone->setTranslateZ(2.0); translatedCone->setChild(prim2); int n = setUnion->addCSGNodeChild(translatedCone); CSGPrimitive* prim3 = new CSGPrimitive(3,1,1); prim3->setSpatialId("sphere0"); prim3->setPrimitiveType("SOLID_SPHERE"); n = setUnion->addCSGNodeChild(prim3); writeSBML(&document, "spatial_example0.xml"); }
BaseObject *Objectify::GetVirtualObjects(BaseObject *op, HierarchyHelp *hh) { BaseDocument *doc = op->GetDocument(); BaseContainer *data = op->GetDataInstance(); BaseObject* obj = (BaseObject*)data->GetLink(CTT_OBJECT_LINK,doc,Obase); LONG crntFrame = doc->GetTime().GetFrame(doc->GetFps()); if (!obj) return NULL; if (obj->GetType() != Ospline){ return NULL; } // start new list op->NewDependenceList(); // check cache for validity and check master object for changes Bool dirty = op->CheckCache(hh) || op->IsDirty(DIRTYFLAGS_DATA); // if child list has been modified if (!dirty) dirty = !op->CompareDependenceList(); // mark child objects as processed op->TouchDependenceList(); dirty = dirty || (prevFrame != crntFrame); prevFrame = crntFrame; // if no change has been detected, return original cache if (!dirty) return op->GetCache(hh); SplineObject* spline = (SplineObject*) obj; AutoAlloc<SplineHelp> splineHelp; StatusSetText("Collecting points"); float positioAlongSpline = data->GetReal(POSITION_ALONG_SPLINE,0.5); positioAlongSpline /= 10000.0f; positioAlongSpline = positioAlongSpline > 1.0 ? 1.0: positioAlongSpline; positioAlongSpline = positioAlongSpline < 0.0 ? 0.0: positioAlongSpline; cout<<positioAlongSpline<<endl; vector<vector<float> > points; for (LONG i = 0; i < spline->GetSegmentCount(); i++){ Vector p = spline->GetSplinePoint(positioAlongSpline, i); vector<float> point; point.push_back(p.x); point.push_back(p.y); point.push_back(p.z); points.push_back(point); } StatusSetText("Collected "+LongToString(points.size())+" points"); ksearchNeighbors= data->GetLong(TRIANGULATION_MAX_NEIGHBORS, 100); gp3SearchRadius = data->GetReal(TRIANGULATION_MAX_SEARCH_RADIUS,30.); gp3MaxNeighbors = data->GetLong(KSEARCH_NEIGHBORS, 20); gp3Mu = data->GetReal(KSEARCH_MU, 0.5); vector<vector<float> > surfacePoints; vector<vector<int> > triIndxs; StatusSetBar(0); StatusSetText("Triangulating"); bool useMls = data->GetBool(USE_MLS, false); tri.computeSurface(points, surfacePoints, triIndxs, ksearchNeighbors, gp3SearchRadius, gp3MaxNeighbors, gp3Mu, useMls); StatusSetBar(100); StatusSetText("Got "+LongToString(triIndxs.size())+" triangles"); if (triIndxs.size() == 0){ return NULL; } PolygonObject* myPoly = PolygonObject::Alloc(surfacePoints.size(),triIndxs.size()); Vector* ppoints = myPoly->GetPointW(); vector<float> sp; for (int t = 0; t < surfacePoints.size()-2; t += 3) { sp = surfacePoints[t]; ppoints[t+0] = Vector(sp[0],sp[1],sp[2]); sp = surfacePoints[t+1]; ppoints[t+1] = Vector(sp[0],sp[1],sp[2]); sp = surfacePoints[t+2]; ppoints[t+2] = Vector(sp[0],sp[1],sp[2]); } for (int t = 0; t < triIndxs.size(); t ++) { myPoly->GetPolygonW()[t] = CPolygon(triIndxs[t][0], triIndxs[t][1], triIndxs[t][2], triIndxs[t][2]); } StatusClear(); myPoly->Message(MSG_UPDATE); return ToPoly(myPoly); BaseThread* bt=hh->GetThread(); BaseObject* main = BaseObject::Alloc(Onull); SplineObject* emptySpline = SplineObject::Alloc(0, SPLINETYPE_LINEAR); ModelingCommandData mcd; mcd.doc = doc; mcd.op = emptySpline; if(!SendModelingCommand(MCOMMAND_JOIN, mcd)){ return NULL; } Error: return NULL; }
Bool ApplinkExporter::Execute(BaseDocument* document, BaseContainer* bc) { matDefault = BaseMaterial::Alloc(Mmaterial); if(!matDefault) return false; Filename fileObjPath; fileObjPath.SetDirectory(bc->GetString(IDC_TMP_FOLDER)); fileObjPath.SetFile(document->GetDocumentName()); fileObjPath.SetSuffix("obj"); Filename fileObjOutPath; fileObjOutPath.SetDirectory(bc->GetString(IDC_TMP_FOLDER)); fileObjOutPath.SetFile("output.obj"); Filename fileImport; fileImport.SetDirectory(bc->GetString(IDC_EXCH_FOLDER)); fileImport.SetFile("import.txt"); GePrint(fileObjPath.GetString()); GePrint(fileObjOutPath.GetString()); GePrint(fileImport.GetString()); const Matrix tM(LVector(0.0f, 0.0f, 0.0f), LVector(1.0f, 0.0f, 0.0f), LVector(0.0f, 1.0f, 0.0f), LVector(0.0f, 0.0f, -1.0f)); //BaseDocument* doc = document->Polygonize(); AutoAlloc<AtomArray> oSel; document->GetActiveObjects(oSel, GETACTIVEOBJECTFLAGS_0); if(oSel->GetCount() > 0) { //Write import.txt// AutoAlloc<BaseFile> basefileImport; if (!basefileImport->Open(fileImport, FILEOPEN_WRITE, FILEDIALOG_NONE, GeGetByteOrder())) return FALSE; this->WriteString(fileObjPath.GetString() + "\n", basefileImport); this->WriteString(fileObjOutPath.GetString() + "\n", basefileImport); this->WriteString(mapType(bc->GetLong(IDC_COMBO_MAP_TYPE)) + "\n", basefileImport); Bool bSkipImp = bc->GetBool(IDC_CHK_SKIP_IMP_DIALOG); if(bSkipImp) { this->WriteString("[SkipImport]\n", basefileImport); } Bool bSkipExp = bc->GetBool(IDC_CHK_SKIP_EXP_DIALOG); if(bSkipExp) { this->WriteString("[SkipExport]\n", basefileImport); } GePrint(mapType(bc->GetLong(IDC_COMBO_MAP_TYPE))); basefileImport->Close(); GePrint("File " + fileImport.GetString() + " write success!"); //Write file.obj// AutoAlloc<BaseFile> objfile; //if (!objfile) return FALSE; if (!objfile->Open(fileObjPath, FILEOPEN_WRITE, FILEDIALOG_NONE, GeGetByteOrder())) return FALSE; String str; str = "#Wavefront OBJ Export for 3D-Coat\n"; this->WriteString(str, objfile); DateTime t; GetDateTimeNow(t); str = "#File created: " + FormatTime("%d.%m.%Y %H:%M:%S", t) + "\n"; this->WriteString(str, objfile); str = "#Cinema4D Version: " + LongToString(GetC4DVersion()) + "\n"; this->WriteString(str, objfile); this->WriteEndLine(objfile); Bool expMat = bc->GetBool(IDC_CHK_EXP_MAT); vpcnt = vtcnt = 0; for(int i = 0; i < oSel->GetCount(); i++) { StatusSetSpin(); PolygonObject* ob = (PolygonObject*) oSel->GetIndex(i); if (ob->GetType() == Opolygon) { StatusSetText("Export object " + ob->GetName()); ExportObject mObject; GePrint("Name " + ob->GetName()); //GePrint("Type " + LongToString(ob->GetType())); if(expMat) { mObject.pmatidxArray.ReSize(ob->GetPolygonCount()); mObject.tempMats.ReSize(1); mObject.pmatidxArray.Fill(0); Bool haveMats = false; ////////////////////////////////////////// for(BaseTag* tag = ob->GetFirstTag(); tag != NULL; tag = tag->GetNext()) { LONG typ = tag->GetType(); if(typ == Ttexture) { if (!getParameterLink(*tag, TEXTURETAG_MATERIAL, Mbase)) continue; haveMats = true; TextureTag* txttag = (TextureTag*)tag; BaseMaterial* material = txttag->GetMaterial(); if(material == NULL) { GePrint("Material not found on " + ob->GetName() + "object."); return false; } //GePrint("Mat Name: " + material->GetName()); String restrict = getParameterString(*tag, TEXTURETAG_RESTRICTION); if (restrict.Content()) { mObject.tempMats.Push(material); //GePrint("Selection: " + restrict); for(BaseTag* seltag = ob->GetFirstTag(); seltag != NULL; seltag = seltag->GetNext()) { LONG seltyp = seltag->GetType(); if(seltyp == Tpolygonselection && seltag->GetName() == restrict) { SelectionTag* selecttag = (SelectionTag*)seltag; BaseSelect* sel = selecttag->GetBaseSelect(); //GePrint("sel data count: " + LongToString(sel->GetCount())); LONG seg = 0, a, b, p; while (sel->GetRange(seg++, &a, &b)) { for (p = a; p <= b; ++p) { //GePrint("seltpolygon: " + LongToString(p)); mObject.pmatidxArray[p] = mObject.tempMats.GetCount()-1; } } } } } else { mObject.tempMats[0] = material; mObject.pmatidxArray.Fill(0); } } } if(!mObject.tempMats[0]) { matDefault->SetName("Default"); BaseChannel* color = matDefault->GetChannel(CHANNEL_COLOR); if (!color) return false; // return some error BaseContainer cdata = color->GetData(); cdata.SetVector(BASECHANNEL_COLOR_EX, Vector(1.0f, 1.0f, 1.0f)); //document->InsertMaterial(matDefault, NULL, FALSE); //matDefault->Update(TRUE, TRUE); //matDefault->Message(MSG_UPDATE); mObject.tempMats[0] = matDefault; //GePrint("Global material not found on object " + ob->GetName() + "."); //return false; } if(haveMats) { //GePrint("mObject.tempMats.GetCount(): " + LongToString(mObject.tempMats.GetCount())); for(LONG m = 0; m < mObject.tempMats.GetCount(); m++) { Bool inMats = false; //GePrint("materialArray.GetCount(): " + LongToString(materialArray.GetCount())); for(LONG n = 0; n < materialArray.GetCount(); n++) { if(mObject.tempMats[m]->GetName() == materialArray[n]->GetName()) { inMats = true; break; } } if(!inMats) { materialArray.Push(mObject.tempMats[m]); } } } //String str1; //for (LONG p = 0; p < ob->GetPolygonCount(); p++) //{ // str1 += LongToString(mObject.pmatidxArray[p]) + ","; //} //GePrint(str1); } ///////////////////////////////////////////////// const Vector* vadr = ob->GetPointR(); const CPolygon* padr = ob->GetPolygonR(); LONG vcnt = ob->GetPointCount(); LONG pcnt = ob->GetPolygonCount(); mObject.Fpvnb.ReSize(pcnt);// poly counts for(LONG p = 0; p < pcnt; p++) { if(padr[p].c != padr[p].d) { mObject.Fpvnb[p] = 4; } else { mObject.Fpvnb[p] = 3; } } mObject.pVertexCount = PVertexLength(mObject); //Vertex positions mObject.Vp.ReSize(vcnt); Matrix mg = tM * ob->GetMgn(); for (LONG v = 0; v < vcnt; v++) { mObject.Vp[v] = vadr[v] * mg; //GePrint("Point[" + LongToString(i) + "] " + LongToString(padr[i].x) + ", " + LongToString(padr[i].y) + ", " + LongToString(padr[i].z)); //str = "v " + LongToString(vadr[p].x) + " " + LongToString(vadr[p].y) + " " + LongToString(vadr[p].z) + "\n"; //this->WriteString(str, objfile); } mObject.Fv.ReSize(mObject.pVertexCount); LONG y=0; for (LONG p = 0; p < pcnt; p++) { if(mObject.Fpvnb[p] == 4) { mObject.Fv[y] = padr[p].d; mObject.Fv[y+1] = padr[p].c; mObject.Fv[y+2] = padr[p].b; mObject.Fv[y+3] = padr[p].a; } else { mObject.Fv[y] = padr[p].c; mObject.Fv[y+1] = padr[p].b; mObject.Fv[y+2] = padr[p].a; } y += mObject.Fpvnb[p]; } //String str1; //for (LONG p = 0; p < mObject.Fv.GetCount(); p++) //{ // str1 += LongToString(mObject.Fv[p]) + " "; //} //GePrint(str1); /////////////////////////////// ///////////vertex UV ////////////////////////////// if(bc->GetBool(IDC_CHK_EXP_UV)) { // Get first UV tag (if at least one) UVWTag* uvw_tag = (UVWTag*)ob->GetTag(Tuvw, 0); if(!uvw_tag) { GePrint("Object \"" + ob->GetName() + "\" has no UVW tag.\nUV coordinates can't be exported."); return FALSE; } else { mObject.Vt.ReSize(mObject.pVertexCount); mObject.Fvt.ReSize(mObject.pVertexCount); const UVWHandle dataptr = uvw_tag->GetDataAddressR(); UVWStruct res; for(LONG t=0, y=0; t < pcnt; t++) { //GePrint("y: " + LongToString(y)); UVWTag::Get(dataptr, t, res); if(mObject.Fpvnb[t] == 4) { mObject.Vt[y] = res.d; mObject.Vt[y + 1] = res.c; mObject.Vt[y + 2] = res.b; mObject.Vt[y + 3] = res.a; mObject.Fvt[y] = y; mObject.Fvt[y + 1] = y + 1; mObject.Fvt[y + 2] = y + 2; mObject.Fvt[y + 3] = y + 3; } else { mObject.Vt[y] = res.c; mObject.Vt[y + 1] = res.b; mObject.Vt[y + 2] = res.a; mObject.Fvt[y] = y; mObject.Fvt[y + 1] = y + 1; mObject.Fvt[y + 2] = y + 2; } y += mObject.Fpvnb[t]; } } //String str1; //for (LONG p = 0; p < mObject.Fvt.GetCount(); p++) //{ // str1 += LongToString(mObject.Fvt[p]) + " "; //} //GePrint(str1); } WriteExportFile(bc, ob, objfile, mObject, vcnt, pcnt); //GePrint("Fvt: " + LongToString(Fvt.GetCount())); vpcnt += mObject.Vp.GetCount(); if(bc->GetBool(IDC_CHK_EXP_UV)) vtcnt += mObject.Vt.GetCount(); } } objfile->Close(); if(expMat && materialArray.GetCount() > 0) WriteMatsFile(document, bc); } else { GePrint("No selected objects!"); } BaseMaterial::Free(matDefault); return TRUE; }
//This method does all the work for the brush. Every time a dab is placed down on the surface this method is called. It will //be called for every symmetrical dab as well, but you do not need to worry about them at all. static Bool SculptMovePointsFunc(BrushDabData *dab) { //Paint First PaintBrushBase::MovePointsFunc(dab); //If the brush strength is 0 then we don't need to do anything. //This is the brush strength from the UI. This has been automatically adjusted by any FX settings and tablet pressure values. if (dab->GetBrushStrength() == 0) return true; //Get the radius of the brush. This is the brush size from the UI. This has been automatically adjusted by any FX settings and tablet pressure values. Float brushRadius = dab->GetBrushRadius(); //If the brush radius is 0 then we don't need to do anything since there won't be any data. if (brushRadius <= 0) return false; //Get the BaseContainer for the brush settings. const BaseContainer *brushData = dab->GetData(); //Get the buildup slider value and adjust it to a usable range. Float buildup = brushData->GetFloat(MDATA_SCULPTBRUSH_SETTINGS_BUILDUP) * 0.002; //Is the dab a preview dab? A Preview dab occurs when in the DragDab or DragRect DrawModes. //This draws to a temporary preview layer while the user is interactively moving the mouse on the surface of the model. Bool usePreview = dab->IsPreviewDab(); //Get the PolygonObject for the current sculpt object. This will be the sculpt object at the current subdivision level. //We are getting access to the PolygonObject so that we can determine its size in the scene. The size will need to be taken //into account to adjust the strength of the offsets. PolygonObject *polyObj = dab->GetPolygonObject(); //If for some reason it does not exist then return. This should never happen but it is better to check and be safe than to just assume everything is ok. if (!polyObj) return false; //Get the radius of the PolygonObject and use this in the calculation to adjust the brush strength. //Very large objects will need to move their points further otherwise the dabs will not be noticeable on the surface of the object. Float dim = Len(polyObj->GetRad()) * 0.005; //Create a multiply vector to move the points by using the brushes strength, normal and the size of the object. Float pressurePreMult = dab->GetBrushStrength() * 10.0 * buildup * dim; //The normal is the average normal of all the vertices for this dab. Vector multPreMult = dab->GetNormal() * pressurePreMult; //If the user is holding down the Ctrl Key then the OVERRIDE_INVERT flag will be set. If it is set then we invert the direction of the multiplier vector. if (dab->GetBrushOverride() & OVERRIDE_INVERT) { multPreMult = -multPreMult; } //The user may also have the invert checkbox enabled in the UI. Check for this and then invert the direction of the multiplier vector again if we need to. if (brushData->GetBool(MDATA_SCULPTBRUSH_SETTINGS_INVERT)) { multPreMult = -multPreMult; } //Loop over very point for this dab and move it if we need to. Int32 a; Int32 count = dab->GetPointCount(); const BrushPointData *pPointData = dab->GetPointData(); for (a = 0; a < count; ++a) { //Get the index of the point on the PolygonObject. Int32 pointIndex = pPointData[a].pointIndex; //Get the falloff for this point. This will always be a value from 0 to 1. //The value returned is a combination of the following values all multiplied together to give a final value. // - The falloff curve. // - The color of the stamp with its color value averaged to gray and adjusted by the Gray Value. // - The color of the stencil with its color value averaged to gray and adjusted by the Gray Value. Float fallOff = dab->GetBrushFalloff(a); //If the falloff value is 0 then we don't have to do anything at all. if (fallOff == 0) continue; //Multiply the falloff value with the multiply vector we calculated early. This will result in an offset vector that we want to move the vertex on the model by. Vector res = fallOff * multPreMult; //If the brush is not in preview mode (preview mode happens with in DragDab or DragRect mode) then we can offset the final point on the selected layer. if (!usePreview) { dab->OffsetPoint(pointIndex, res); } //Otherwise we apply the offset to the preview layer. else { dab->OffsetPreviewPoint(pointIndex, res); } } return true; }
void Cocos2dxView::saveObjectData(JsonX &data, BaseObject *object) { std::string tmp = object->getTypeName(); const char *type_name = tmp.c_str(); ObjectType type = object->getObjectType(); if (!data.has(type_name)) data.insertArray(type_name); //存储同一类型对象的通用属性到数组对象 rapidjson::Value &arr = data[type_name]; if (type == ObjectType::COMMON_OBJECT) { if (!getObjectAttr(type_name, object->getFileName())) return; rapidjson::StringBuffer buf; rapidjson::Writer<rapidjson::StringBuffer> writer(buf); getObjectAttr(type_name, object->getFileName())->getDocument().Accept(writer); rapidjson::Document attr(&data.getAllocator()); attr.Parse<0>(buf.GetString()); rapidjson::Value v(object->getFileName().c_str(), data.getAllocator()); attr.AddMember("filename", v, data.getAllocator()); arr.PushBack((rapidjson::Value&)attr, data.getAllocator()); } else if (type == ObjectType::CIRCLE_OBJECT) { CircleObject *circle = (CircleObject *)object; rapidjson::Document attr(&data.getAllocator()); attr.SetObject(); rapidjson::Value point(rapidjson::kObjectType); point.AddMember("x", circle->getCenterPoint().x, data.getAllocator()); point.AddMember("y", circle->getCenterPoint().y, data.getAllocator()); attr.AddMember("center", point, data.getAllocator()); attr.AddMember("radius", circle->getRadius(), data.getAllocator()); arr.PushBack((rapidjson::Value&)attr, data.getAllocator()); } else if (type == ObjectType::POLYGON_OBJECT) { PolygonObject *polygon = (PolygonObject*)object; rapidjson::Document attr(&data.getAllocator()); attr.SetObject(); //存储形状点集 rapidjson::Value shape_arr(rapidjson::kArrayType);//shape_arr.SetArray() for (auto pos : polygon->getPolyPoints()) { rapidjson::Value point(rapidjson::kObjectType); point.AddMember("x", pos.x, data.getAllocator()); point.AddMember("y", pos.y, data.getAllocator()); shape_arr.PushBack(point, data.getAllocator()); } attr.AddMember("shape", shape_arr, data.getAllocator()); arr.PushBack((rapidjson::Value&)attr, data.getAllocator()); } //保存对象的特定属性 rapidjson::Value &attr = (rapidjson::Value&)object->getObjectAttribute(); for (auto iter = attr.MemberonBegin(); iter != attr.MemberonEnd(); iter++) { rapidjson::Value k(iter->name.GetString(), data.getAllocator()); rapidjson::Value v(iter->value.GetString(), data.getAllocator()); arr[arr.Size() - 1].AddMember(k, v, data.getAllocator()); } //保存对象常规属性 //rapidjson::Value &arr = data[type_name]; rapidjson::Value v(rapidjson::kObjectType); v.AddMember("x", object->getPositionX(), data.getAllocator()); v.AddMember("y", object->getPositionY(), data.getAllocator()); arr[arr.Size() - 1].AddMember("position", v, data.getAllocator()); rapidjson::Value sv(rapidjson::kObjectType); sv.AddMember("width", object->getSprite()->getContentSize().width, data.getAllocator()); sv.AddMember("height", object->getSprite()->getContentSize().height, data.getAllocator()); arr[arr.Size() - 1].AddMember("size", sv, data.getAllocator()); arr[arr.Size() - 1].AddMember("rotate", object->getRotation(), data.getAllocator()); arr[arr.Size() - 1].AddMember("scale", object->getScale(), data.getAllocator()); }