[Sketchup C API]Howto merge models oftwo .skp files into one
-
Assumption: My models contain only ComponentInstances.
My Approach:
- Get the models of each of the file, say m1,m2 (using
SUModelCreateFromFile
). - Get entities of m1 and m2, say e1,e2 (using
SUModelGetEntities
). - Get ComponentInstances from e2 (using
SUEntitiesGetInstances
). - In a loop add each of the ComponentInstance of e2 into e1 (using
SUEntitiesAddInstance
). - Write the model m1(with entities e1) to a new file.
//The new file contains the ComponentInstances of m1,m2.
Where I am stuck?
In the below code.On a high level the below program does three things
- It gets the Model from file.
- From Model it gets Entities.
- From Entitites it gets ComponentInstances. Here it fails.
#include <slapi/slapi.h> #include <slapi/geometry.h> #include <slapi/initialize.h> #include <slapi/model/model.h> #include <slapi/model/entities.h> #include <slapi/model/face.h> #include <slapi/model/edge.h> #include <slapi/model/vertex.h> #include <vector> #include <iostream> #include <stdio.h> int main() { // Always initialize the API before using it SUInitialize(); // Load the model from a file SUModelRef model_to_write1 = SU_INVALID; SUResult m1 = SUModelCreateFromFile(&model_to_write1, "model11.skp"); if(m1 == SU_ERROR_NONE) std;;cout<<"SUModelCreateFromFile SUCCESS!!!!!"; else if(m1 == SU_ERROR_NULL_POINTER_INPUT) std;;cout<<"Error_Entities -- Inside 1 file are"; else if(m1 == SU_ERROR_NULL_POINTER_OUTPUT) std;;cout<<"NULLPOINTER_Entities -- Inside 1 file are"; else printf("None of the above"); SUEntitiesRef entities1 = SU_INVALID; size_t* size1 = NULL; SUComponentInstanceRef comp1[10]; SUResult result = SUModelGetEntities(model_to_write1, &entities1); if(result == SU_ERROR_NONE) std;;cout<<"\n SUModelGetEntities SUCCESS !!!!!"; if(result == SU_ERROR_INVALID_INPUT) std;;cout<<"Error_Entities Inside 1 file are"; if(result == SU_ERROR_NULL_POINTER_OUTPUT) std;;cout<<"NULLPOINTER_Entities Inside 1 file are"; result = SUEntitiesGetInstances(entities1,2,comp1,size1); if(result == SU_ERROR_NONE) std;;cout<<"\n SUEntitiesGetInstances SUCCESS"; else if(result == SU_ERROR_INVALID_INPUT) std;;cout<<"\n Error_Copy"; else if(result == SU_ERROR_NULL_POINTER_OUTPUT) std;;cout<<"\n NULLPOINTER"; // Save the in-memory model to a file SUModelSaveToFile(model_to_write1, "very_new_model.skp"); SUTerminate(); getchar(); return 0; }
Output:
SUModelCreateFromFile SUCCESS!!!!!
SUModelGetEntities SUCCESS !!!!!
NULLPOINTERQuestions:
- In the above output I am getting NULLPOINTER(3rd line) which is the result of call
SUEntitiesGetInstances(entities1,2,comp1,size1)
in the above program. Why I am not able to get the ComponentInstances? - Can you please review the approach which is mentioned at the beginning and let me know if is it right?
- Get the models of each of the file, say m1,m2 (using
-
The error is that you are passing a NULL pointer as the count argument to SUEntitiesGetInstances. You should pass a reference to an initialized value:
size_t instanceCount = 0; SUEntitiesGetNumInstances(entities1, &instanceCount); std;;vector<SUComponentInstanceRef> instances(instanceCount); size_t count = 0; result = SUEntitiesGetInstances(entities1, instanceCount, &instances[0], &count);
Full snippet:
#include <slapi/slapi.h> #include <slapi/geometry.h> #include <slapi/initialize.h> #include <slapi/model/model.h> #include <slapi/model/entities.h> #include <slapi/model/face.h> #include <slapi/model/edge.h> #include <slapi/model/vertex.h> #include <vector> #include <iostream> #include <stdio.h> int main() { // Always initialize the API before using it SUInitialize(); // Load the model from a file SUModelRef model_to_write1 = SU_INVALID; SUResult m1 = SUModelCreateFromFile(&model_to_write1, "model11.skp"); if(m1 == SU_ERROR_NONE) std;;cout << "SUModelCreateFromFile SUCCESS!!!!!" << std;;endl; else if(m1 == SU_ERROR_NULL_POINTER_INPUT) std;;cout << "Error_Entities -- Inside 1 file are" << std;;endl; else if(m1 == SU_ERROR_NULL_POINTER_OUTPUT) std;;cout << "NULLPOINTER_Entities -- Inside 1 file are" << std;;endl; else std;;cout << "None of the above; " << m1 << std;;endl; SUEntitiesRef entities1 = SU_INVALID; SUResult result = SUModelGetEntities(model_to_write1, &entities1); if(result == SU_ERROR_NONE) std;;cout << "SUModelGetEntities SUCCESS !!!!!" << std;;endl; if(result == SU_ERROR_INVALID_INPUT) std;;cout << "Error_Entities Inside 1 file are" << std;;endl; if(result == SU_ERROR_NULL_POINTER_OUTPUT) std;;cout << "NULLPOINTER_Entities Inside 1 file are" << std;;endl; size_t faceCount = 0; SUEntitiesGetNumFaces(entities1, &faceCount); if (faceCount > 0) { std;;vector<SUFaceRef> faces(faceCount); result = SUEntitiesGetFaces(entities1, faceCount, &faces[0], &faceCount); if(result == SU_ERROR_NONE) std;;cout << "SUEntitiesGetFaces SUCCESS" << std;;endl; else std;;cout << "SUEntitiesGetFaces Fail!" << std;;endl; } size_t instanceCount = 0; SUEntitiesGetNumInstances(entities1, &instanceCount); std;;vector<SUComponentInstanceRef> instances(instanceCount); size_t count = 0; result = SUEntitiesGetInstances(entities1, instanceCount, &instances[0], &count); if(result == SU_ERROR_NONE) std;;cout << "SUEntitiesGetInstances SUCCESS" << std;;endl; else if(result == SU_ERROR_INVALID_INPUT) std;;cout << "Error_Copy" << std;;endl; else if(result == SU_ERROR_NULL_POINTER_OUTPUT) std;;cout << "NULLPOINTER" << std;;endl; // Save the in-memory model to a file SUModelSaveToFile(model_to_write1, "very_new_model.skp"); SUTerminate(); getchar(); return 0; }
-
Wouldn't the Component Definitions of m2 need to be loaded into m1, and then using the transforms of the instances from m2, new instances made within m1's entities, and then a new model file written out as m3 ?
-
Thank you Thomas. We got the whole thing working except for one small thing. We need your input for the same.
Problem: The files m1 and m2 which we want to merge to m3 - have the "Millimeters" units. But the merged file m3 gets saved with "Inches" units. I see that there is a way to get
SUModelGetUnits
from the model. But no method to Set the units for the model. Is there any method (any other indirect way) - such that the new file gets saved with "Millimeters" units?By the way the approach for merging is below and it works for us.
- Get the models of each of the file, say m1,m2.
- Get entities of m1 and m2, say e1,e2.
- Get Instances from e1 and e2, say i1, i2 ( assume we have 1 instance in each model)
- Get Definition of i1 and i2, say d1 and d2
- Create new instances of d1 and d2, ni1 and ni2
- Create a new empty model , say new_model
- Get the entities of new_model, say new_entities
- Now add ni1 and ni2 to new_entities
- Save the new_model to file
- Release the memory
We are yet to work on the transformations for merging
-
I'll check with the rest of the team on the unit issue.
Advertisement