Menu

Multi material object

Help
2017-05-16
2018-09-25
  • Massimo Zanoletti

    Hi to all

    I'll use the TGLArrowLine object as a sample to show you what I need.
    As you know, ArrowLine is a "single" object; but you can imagine 3 different parts of it: top cap (a cone that is the head); bottom cap (a cone that is the tail) and the line itself (a clylinder).
    The ArrowLine object has obviously a material associated to it; this material "paints" all 3 parts with the same material.
    And now the question.
    I have a single object that is very similar to the ArrowLine (built by different parts), and I would paint each part with different materials.
    It's mandatory not to use 3 different separated objects.
    Any suggestion to do it?

    Thanks in advance
    Massimo Zanoletti

     
  • Jerome.D (BeanzMaster)

    Hi Massimo it's depend how you build your object. Do you herit from a TGLObject ? Do you pass thru FreeForms ? DirectOpenGL ?

    In your functions take a look a the RenderingContext (RCI) when it's avaible, with you'll can have access to OpenGL's States and others.

    With freeform it's easy create 3 SubMesh set UV/Normals according to how you want assign texture (only 1 or 2 or 3)

    In Herited object you need play with BuiltList, Render(Object) functions (If i'm remember it's the rights name) and of course play with opengl's functions only with DirectOpenGL

     
  • Massimo Zanoletti

    Thanks for answer.
    My object isn't already implemented.
    I want to find the best solution to do it.
    So, I can consider to use a mesh object.

    Probably it should be better if I give more details.
    Think to the object as a polygon. Vertexes of polygon will be known at runtime only.
    Polygon must be extruded, and the front face must have a material, the side (extrusion) another material, and the back polygon another one again.
    Moreover, polygons can have holes.
    A good example could be a character; the A for example.

     
  • Jerome.D (BeanzMaster)

    Ok i understand i think the better is TGLMeshObjet. You can take loo at a the attached unit here, it will help you a little :)

     
  • Massimo Zanoletti

    Hi Jerome

    I tried with the mesh object
    I create different mesh objects and then I insert them into the same FreeForm (it's what I need).
    But I can't assign different materials to them
    I can only assign the material to whole FreeForm, but in this way all mesh objects will have the same material

     
  • Jerome.D (BeanzMaster)

    Hi Massimo Take a look at the TGLFaceGroup you must create one for each sub object and set MatrerialName property

     
  • Massimo Zanoletti

    Hi Jerome.

    I attached a very simple demo app.
    I tried but...
    There are 2 buttons
    The first just create 2 meshes inside the same FreeForm object (and it wokrs)
    The second one try to connect to different materials

     
  • Jerome.D (BeanzMaster)

    Hi Massimo simply (LOL) just change

    procedure TForm1.BtnConnectMatClick(Sender: TObject);
    begin
       // Cylinder should be red
       FrForm1.MeshObjects[0].FaceGroups[0].MaterialName := 'MatRed';
       // Cube should be green
       FrForm1.MeshObjects[1].FaceGroups[0].MaterialName := 'MatGreen';
       FrForm1.MeshObjects[0].FaceGroups[0].PrepareMaterialLibraryCache(MatLibr);
       FrForm1.MeshObjects[1].FaceGroups[0].PrepareMaterialLibraryCache(MatLibr);
    end;
    

    by

    procedure TForm1.BtnConnectMatClick(Sender: TObject);
    begin
       // Cylinder should be red
       FrForm1.MaterialLibrary:=MatLibr;
       FrForm1.MeshObjects[0].FaceGroups[0].MaterialName := 'RedMat';
       // Cube should be green
       FrForm1.MeshObjects[1].FaceGroups[0].MaterialName := 'GreenMat';
    
       //Prepare matcache for all MESHOBECTS AND FaceGroups. It work but something is wrong with that. 
       // Normaly just the 1st MeshObject's facegroups'MatCache will be altered.
    
       FrForm1.MeshObjects[0].FaceGroups.PrepareMaterialLibraryCache(MatLibr);   
       // FrForm1.MeshObjects[0].FaceGroups[0].PrepareMaterialLibraryCache(MatLibr);
       // FrForm1.MeshObjects[1].FaceGroups[0].PrepareMaterialLibraryCache(MatLibr);
    
    end;
    

    :)

     

    Last edit: Jerome.D (BeanzMaster) 2017-06-12
  • Massimo Zanoletti

    Thank you very much, Jerome

     
  • Massimo Zanoletti

    Hi Jerome
    I'm back here because I need another little help
    Your previous suggestion works fine, but is not exactly what I need.
    I had a mistake when in the little sample I used the MeshHelper class objects (I used them just for speed in sample), but in my real application I will not use that class, and unfortunately it seems that your suggestion works only for Helper class.
    My real application uses the TGLMeshObject class, but (most important) mesh is built starting from triangles (I have some shapes built by tringles), so the "Mode" is set in momTriangles.
    and I don't know how to apply different materials in this situation.

    I provided a little sample.
    I left the previous code inside, and I added new code to show.
    When the check box is checked, the sample works exactly as before, using the Helper class and you suggestion (and it works).
    When checkbox is unchecked, the first button builds two meshes starting from triangles (a simple house and a simple arrow), but then the connect material button ...

    Please take a look if you can

    Thanks in advance
    Massimo

     
  • Jerome.D (BeanzMaster)

    Hi Massimo, i taked a quick look first becarefull with material spelling Name in the code you have GreenMat and RedMat but you've declared MatRed and MatGreen in materialLibrary (same error as before)

    2nd
    ` MObjStd2 := TGLMeshObject.CreateOwned (FrForm1.MeshObjects);
    MObjStd2.Mode := momTriangles;
    MObjStd2.Name := 'Arrow';
    MObjStd2.Vertices.Add (AffineVectorMake (2.0, -0.5, 2.0));
    MObjStd2.Vertices.Add (AffineVectorMake (5.0, -0.5, 2.0));
    MObjStd2.Vertices.Add (AffineVectorMake (2.0, +0.5, 2.0));

    MObjStd2.Vertices.Add (AffineVectorMake (2.0, +0.5, 2.0));
    MObjStd2.Vertices.Add (AffineVectorMake (5.0, -0.5, 2.0));
    MObjStd2.Vertices.Add (AffineVectorMake (5.0, +0.5, 2.0));

    MObjStd2.Vertices.Add (AffineVectorMake (5.0, -1.0, 2.0));
    MObjStd2.Vertices.Add (AffineVectorMake (6.0, +0.0, 2.0));
    MObjStd2.Vertices.Add (AffineVectorMake (5.0, +1.0, 2.0));`

    Here is not enought, Here is just one object, no submesh, no faces group so you can only attach ONE material. For what you want, you need to declare Face's indices in a Face's groups for each part of your object

    See in GLMeshObjectHelper :

    `
    constructor TGLCustomEditingMeshObject.Create;
    begin
    inherited Create;
    FFaceList := TFGVertexIndexList.CreateOwned(self.FaceGroups); --> FaceList
    FFaceList.Mode := fgmmQuads; // fgmmTriangles; ---> Here is what you search
    Mode := momFaceGroups;
    self.UseVBO := true;

    end;
    procedure TGLCustomEditingMeshObject.AddFace(v1, v2, v3: TVector);
    var
    i1, i2, i3: Integer;
    begin
    i1 := AddVertice(v1.V[0], v1.V[1], v1.V[2]);
    i2 := AddVertice(v2.V[0], v2.V[1], v2.V[2]);
    i3 := AddVertice(v3.V[0], v3.V[1], v3.V[2]);
    FFaceList.VertexIndices.Add(i1, i2, i3); ---> take a look at this
    end;`

    For each material in GLMeshObject you'll need to create in order Vertices-->FaceGroups -->FacesList.
    And finally set the good material to the right facegroup.

     

    Last edit: Jerome.D (BeanzMaster) 2017-07-18
  • sxbug

    sxbug - 2018-09-24

    Hi

    [dcc32 Error] glmeshobjecthelper.pas(44): E2003 Undeclared identifier: 'TGLMeshObject'

    I am using GLScene 1.7. How can I do? Thanks

     
  • sxbug

    sxbug - 2018-09-24

    I have changed to TMeshObject, Is it correct?
    Thanks

     
  • Pavel Vassiliev

    Pavel Vassiliev - 2018-09-24

    sxbug,
    Yes it is. Renaming to TGLMeshObject needs to change glsm files format for correct saving scenes.
    PW

     
  • sxbug

    sxbug - 2018-09-25

    Hi
    I want to make some cross-section with many points (each cross-section make up by 30000 points), each cross-section is set to different colors according to the parameter 'form1.MyRecArray^[i].piancha[j])'. Now the following program is running wrong .How do I modify these code?

    procedure TForm2.ConnectMaterialStandard;
    begin
    GLFreeForm1.MaterialLibrary:=GLMaterialLibrary1;

    if MObjStd1<>nil then
    GLFreeForm1.MeshObjects[0].FaceGroups[0].MaterialName := 'LimeMat'; //Exception class $C0000005 with message'C0000005 ACCESS_VIOLATION'
    if MObjStd2<>nil then
    GLFreeForm1.MeshObjects[1].FaceGroups[0].MaterialName := 'YellowMat';
    if MObjStd3<>nil then
    GLFreeForm1.MeshObjects[2].FaceGroups[0].MaterialName := 'RedMat';
    end;

    procedure TForm2.CreateMeshStandard(CircleCount:integer);
    var
    i,j:integer;
    begin
    for i:=0 to CircleCount-1 do begin
    if (abs(form1.MyRecArray^[i].piancha[j])< 0.1) then begin
    MObjStd1 := TMeshObject.CreateOwned (GLFreeForm1.MeshObjects);
    MObjStd1.Mode := momTriangles;
    MObjStd1.Name := 'zcjm'+inttostr(i);
    for j := 0 to form1.MyRecArray^[i].pcount-1 do begin
    MObjStd1.Vertices.Add (AffineVectorMake (form1.MyRecArray^[i].zuobiao[j,0], form1.MyRecArray^[i].zuobiao[j,1], form1.MyRecArray^[i].jl));
    end;
    end
    else if (abs(form1.MyRecArray^[i].piancha[j])>= 0.1) and (abs(form1.MyRecArray^[i].piancha[j])<1) then begin
    MObjStd2 := TMeshObject.CreateOwned (GLFreeForm1.MeshObjects);
    MObjStd2.Mode := momTriangles;
    MObjStd2.Name := 'zdjm'+inttostr(i);
    for j := 0 to form1.MyRecArray^[i].pcount-1 do begin
    MObjStd2.Vertices.Add (AffineVectorMake (form1.MyRecArray^[i].zuobiao[j,0], form1.MyRecArray^[i].zuobiao[j,1], form1.MyRecArray^[i].jl));
    end;
    end
    else begin
    MObjStd3 := TMeshObject.CreateOwned (GLFreeForm1.MeshObjects);
    MObjStd3.Mode := momTriangles;
    MObjStd3.Name := 'bcjm'+inttostr(i);
    for j := 0 to form1.MyRecArray^[i].pcount-1 do begin
    MObjStd3.Vertices.Add (AffineVectorMake (form1.MyRecArray^[i].zuobiao[j,0], form1.MyRecArray^[i].zuobiao[j,1], form1.MyRecArray^[i].jl));
    end;
    end
    end;
    end;

    Thanks!!!!

     
  • sxbug

    sxbug - 2018-09-25

    Hi

    I have Replaced that code with material processing to 'GLFreeForm1.MeshObjects[0].PrepareMaterialLibraryCache(GLMaterialLibrary1)' . But It is only part of the point can be see, and they were irregular. After exporting the OBJ file, the file has some content (just like # OBJ-File exported by GLScene

    Mesh 1

    v 152.017196655273 90.8466567993164 157
    v 152.053604125977 90.9035186767578 157
    v 152.097244262695 90.9611663818359 157), But the 3dsmax is still unable to import. How do I deal with this problem? I want to see the shape.

    Thanks

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.