Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Recent
    • Tags
    • Users
    • Login
    The Maxon SDK Team is currently short staffed due to the winter holidays. No forum support is being provided between 15/12/2025 and 5/1/2026. For details see Maxon SDK 2025 Winter Holidays.

    Normal Tags

    Scheduled Pinned Locked Moved SDK Help
    12 Posts 0 Posters 888 Views
    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.
    • H Offline
      Helper
      last edited by

      THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

      On 23/11/2005 at 06:42, xxxxxxxx wrote:

      User Information:
      Cinema 4D Version:   9.1+ 
      Platform:      Mac OSX  ; 
      Language(s) :     C++  ;

      ---------
      Hello,
      I am trying to read and write Normal Tag data without success yet.
      I understand that the data is stored as a Real value within the WORD values ax...dz, but how do I access these values?
      Any ideas?

      1 Reply Last reply Reply Quote 0
      • H Offline
        Helper
        last edited by

        THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

        On 23/11/2005 at 21:22, xxxxxxxx wrote:

        What do you mean by 'Normal Tags' -- Just a tag that you put on objects in c4d? Sorry for my lack of understanding. I'll try to help if I can. And what are the "WORD" values? Are you by chance thinking of tag containers, or am I completely missunderstanding?

        Aaron M.

        1 Reply Last reply Reply Quote 0
        • H Offline
          Helper
          last edited by

          THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

          On 24/11/2005 at 00:13, xxxxxxxx wrote:

          Hi Aaron,
          I am talking about that kind of tags that is generated by Rhino or other NURBS or CAD modellers to store the surface normals in.
          Within the SDK this type of tag is labled with Tnormal and the original description there is:

          Normals tag. (Contains 12 WORDs per polygon, enumerated like the following: ax,ay,az,bx,by,bz,cx,cy,cz,dx,dy,dz. The value is the Real value of the normal vector component multiplied by 32000.0.)

          Finding and reading out the tag data is no problem. I just have no idea how to read and write the ax, ay ... etc components.

          1 Reply Last reply Reply Quote 0
          • H Offline
            Helper
            last edited by

            THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

            On 24/11/2005 at 00:25, xxxxxxxx wrote:

            Arndt, Tnormal is derived from VariableTag (see docs). That might get you started on finding those values! 🙂

            1 Reply Last reply Reply Quote 0
            • H Offline
              Helper
              last edited by

              THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

              On 24/11/2005 at 01:09, xxxxxxxx wrote:

              Hi Robert,
              yes, thank you, I already know that (see copied Tnormal description in my last posting).
              It's just that I have no idea how to access those Real elements.

              Right now I am using:

              VariableTag *tag=NULL;
              Real *Normale=NULL;
              LONG Elements;

              tag=(VariableTag* )object->GetFirstTag();
              while (tag)
                  {
                  if (tag->IsInstanceOf(Tnormal))
                       {
                       Normale=static_cast<Real*>(tag->GetDataAddress());
                       Elements=tag->GetDataCount(); // Polygone

              for (i=0; i<Elements; i++)
                            {
                             // Is Real the right type for the tag data array?
                             // How do I get ax, ay, az etc. here?
                             }
                        }
                    tag=(VariableTag* )tag->GetNext();
                   }

              1 Reply Last reply Reply Quote 0
              • H Offline
                Helper
                last edited by

                THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                On 24/11/2005 at 02:46, xxxxxxxx wrote:

                I think their clue is that the data contains an array of '12-WORD' values, the array being 12 WORDs * polygon count. As to the procedure for extracting the data, I have no idea. It seems that the WORDs are pseudo-integers which need to be divided by 32000.0 to get the REAL value back out:

                WORD* Normale = NULL;
                ...
                ax = (Real)Normale[n] / 32000.0; (or more efficiently multiplied by 1/32000.0 = 0.00003125)
                (etc.)

                Your best bet to determine whether one element of the array is 12-WORDs or 1-WORD is to use GetDataSize() and see what it returns. But, I donot think that the data is parsed out in either polygons or Real values, but in WORDs which need interpretation.

                1 Reply Last reply Reply Quote 0
                • H Offline
                  Helper
                  last edited by

                  THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                  On 24/11/2005 at 09:24, xxxxxxxx wrote:

                  Hi Robert,
                  the problem is that looking at the data count with tag->GetDataCount() gives the number of polygons of that object.
                  So the array has only as many elements as there are polygons, but as there are 12 numbers stored for each polygon within that array, I have no idea how the read them out.
                  I already tried to add .ax, .ay etc to the read out value. Doesn't seem to work that way:
                  Real value=Normale _.ax

                  1 Reply Last reply Reply Quote 0
                  • H Offline
                    Helper
                    last edited by

                    THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                    On 24/11/2005 at 11:24, xxxxxxxx wrote:

                    Hello Arndt,

                    My thinking is that there is no single 'element'. You'll need to extract 12 WORDs at a time, into a temporary buffer perhaps:

                      
                    VariableTag* tag=NULL;  
                    WORD* Normale=NULL;  
                    LONG Elements;  
                    WORD wNormal[12];  
                    LONG j;  
                      
                    tag=(VariableTag* )object->GetFirstTag();  
                    while (tag)  
                    {  
                         if (tag->IsInstanceOf(Tnormal))  
                         {  
                              Normale=static_cast<WORD*>(tag->GetDataAddress());  
                              Elements=tag->GetDataCount(); // Polygone  
                                
                              for (j=0; j<Elements; j++)  
                              {  
                                   CopyMem(Normale[j],&wNormal;[0],12*sizeof(WORD));  
                                   // Each component is then an index into wNormal  
                                   // i.e.: ax = wNormal[0], dz = wNormal[11]  
                              }  
                         }  
                         tag=(VariableTag* )tag->GetNext();  
                    }  
                    

                    Note that you still need to do the conversion (Real = WORD / 32000.0) and the referencing of Normale might need to be &Normale;[j][0] or you may need to increment Normale by 12 WORDs each time (Normale += 12 for each j loop). Not certain.

                    1 Reply Last reply Reply Quote 0
                    • H Offline
                      Helper
                      last edited by

                      THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                      On 25/11/2005 at 02:31, xxxxxxxx wrote:

                      Thank you very much Robert, but this doesn't work either.
                      In the meantime I got a hot tip from MAXON about this. Here is the solution:

                      struct NormalStruct
                      {
                           Vector a,b,c,d;
                      };

                      NormalStruct NormalTag::GetNormals(LONG i)
                      {
                           NormalStruct ns;
                           i*=12;
                           WORD *ndata=(WORD* )t_data;

                      ns.a=Vector(ndata[i+0],ndata[i+1],ndata[i+2])/32000.0;
                           ns.b=Vector(ndata[i+3],ndata[i+4],ndata[i+5])/32000.0;
                           ns.c=Vector(ndata[i+6],ndata[i+7],ndata[i+8])/32000.0;
                           ns.d=Vector(ndata[i+9],ndata[i+10],ndata[i+11])/32000.0;

                      return ns;
                      }

                      1 Reply Last reply Reply Quote 0
                      • H Offline
                        Helper
                        last edited by

                        THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                        On 25/11/2005 at 11:33, xxxxxxxx wrote:

                        Well, I'm so glad that they passed this information along in the SDK documentation! 😉

                        1 Reply Last reply Reply Quote 0
                        • H Offline
                          Helper
                          last edited by

                          THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                          On 26/11/2005 at 03:32, xxxxxxxx wrote:

                          Well the SDK docs say:
                          "Normals tag. (Contains 12 WORDs per polygon, enumerated like the following: ax,ay,az,bx,by,bz,cx,cy,cz,dx,dy,dz. The value is the Real value of the normal vector component multiplied by 32000.0.)"
                          Thats pretty clear. It tells you there are 12 WORDs per polygon, and what those 12 WORDS are (x,y,z) for the a,b,c,d of each polygon, plus how to get from the WORD value to the real ones.

                          1 Reply Last reply Reply Quote 0
                          • H Offline
                            Helper
                            last edited by

                            THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                            On 26/11/2005 at 11:40, xxxxxxxx wrote:

                            If 'twere so clear, why does this thread exist? ;0)

                            I had a general idea about how it might work only from working with other VariableTags. But I didn't have time to do the actual testing (just a tad busy updating and fixing one of my plugins) and hadn't the need to deal with them previously.

                            Clarity is contextual. 🙂

                            1 Reply Last reply Reply Quote 0
                            • First post
                              Last post