sketchucation logo sketchucation
    • Login
    ℹ️ Licensed Extensions | FredoBatch, ElevationProfile, FredoSketch, LayOps, MatSim and Pic2Shape will require license from Sept 1st More Info

    [Sketchup C API]Howto merge models oftwo .skp files into one

    Scheduled Pinned Locked Moved Developers' Forum
    5 Posts 3 Posters 657 Views 3 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • R Offline
      rahulnejanawar
      last edited by

      Assumption: My models contain only ComponentInstances.

      My Approach:

      1. Get the models of each of the file, say m1,m2 (using SUModelCreateFromFile).
      2. Get entities of m1 and m2, say e1,e2 (using SUModelGetEntities).
      3. Get ComponentInstances from e2 (using SUEntitiesGetInstances).
      4. In a loop add each of the ComponentInstance of e2 into e1 (using SUEntitiesAddInstance).
      5. 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

      1. It gets the Model from file.
      2. From Model it gets Entities.
      3. 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 !!!!!
      NULLPOINTER

      Questions:

      1. 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?
      2. Can you please review the approach which is mentioned at the beginning and let me know if is it right?

      model11.skp

      1 Reply Last reply Reply Quote 0
      • tt_suT Offline
        tt_su
        last edited by

        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;
        }
        
        
        1 Reply Last reply Reply Quote 0
        • Dan RathbunD Offline
          Dan Rathbun
          last edited by

          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 ?

          I'm not here much anymore.

          1 Reply Last reply Reply Quote 0
          • R Offline
            rahulnejanawar
            last edited by

            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.

            1. Get the models of each of the file, say m1,m2.
            2. Get entities of m1 and m2, say e1,e2.
            3. Get Instances from e1 and e2, say i1, i2 ( assume we have 1 instance in each model)
            4. Get Definition of i1 and i2, say d1 and d2
            5. Create new instances of d1 and d2, ni1 and ni2
            6. Create a new empty model , say new_model
            7. Get the entities of new_model, say new_entities
            8. Now add ni1 and ni2 to new_entities
            9. Save the new_model to file
            10. Release the memory

            We are yet to work on the transformations for merging

            1 Reply Last reply Reply Quote 0
            • tt_suT Offline
              tt_su
              last edited by

              I'll check with the rest of the team on the unit issue.

              1 Reply Last reply Reply Quote 0
              • 1 / 1
              • First post
                Last post
              Buy SketchPlus
              Buy SUbD
              Buy WrapR
              Buy eBook
              Buy Modelur
              Buy Vertex Tools
              Buy SketchCuisine
              Buy FormFonts

              Advertisement