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
    • Register
    • Login

    Tool plugin selecting points?

    Scheduled Pinned Locked Moved SDK Help
    8 Posts 0 Posters 630 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 01/10/2005 at 10:57, xxxxxxxx wrote:

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

      ---------
              Howdy,

      I've made a tool to go with a tag that will select points on an object. It works ok so far except that I'm not sure how to get it to not select the points on the back side of the object that can't be seen from the point of view of the camera. I did a search here and in the archive but couldn't come up with any answers.

      I tried this but it doesn't seem to be working:

      while (win->MouseDrag(&dx;,&dy;,&device;)==MOUSEDRAG_CONTINUE)
           {
                mx+=dx;
                my+=dy;
                mDrag = TRUE;
                for(i=0; i<ptCount; i++)
                {
                     if(bd->TestPointZ(bd->WC(opActive->GetMg() * padr{i})))
                     {
                          opt = bd->WS(opActive->GetMg() * padr{i});
                          opt.z = 0.0;
                          mpt.x = mx;
                          mpt.y = my;
                          mpt.z = 0.0;
                          if(Len(opt-mpt) < rad) bs->Select({i});
                     }
                }
                DrawViews(DA_ONLY_ACTIVE_VIEW|DA_NO_THREAD|DA_NO_ANIMATION);
           }

      I don't know if that is the correct function to use but it was the only thing I could find in the SDK that looked like the right function.

      How do I test to see if the point is on the back side of the object?

      Adios,
      Cactus Dan

      P.S. the regular brackets for the arrays are supposed to be square brackets, but it looks like that's forum code for italic type. I had to edit the post 5 times. 😞

      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 01/10/2005 at 12:33, xxxxxxxx wrote:

        Easiest approach is to do a 'backfacing polygon' check using the camera location as the reference. This is usually done after projecting the polygon into 2D. If the winding order of the polygon's points are opposite forwardfacing polygons, its points can safely be ignored.

        As for the italic thing, I usually just edit my source in NotePad or something to change the index from 'i' to something else (not 'b' for bold, of course).

        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 01/10/2005 at 16:05, xxxxxxxx wrote:

          Howdy,

          That sounds pretty good, but what if the polygons surrounding the point are facing front but theres another part of the object blocking the point from view. I want to have the same option as the selection tool "Only Select Visible Elements".

          A point could be facing front but could be also hidden by something in front of it. I at first considered using the BadkfaceCulling() function from BaseView, but realized that the above described situation would cause that not to work.

          Here's what the SDK says:
          Bool TestPointZ(const Vector& p)

          Returns TRUE if the point is visible in the view according to the current projection. The point must be in camera space.

          Return
          Bool

          TRUE if the point is visible, otherwise FALSE.

          Parameters
          const Vector& p

          Point.

          But that doesn't seem to work. How else could I detect that the point is hidden from view?

          Adios,
          Cactus Dan

          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 01/10/2005 at 17:35, xxxxxxxx wrote:

            Well, yes. That won't work. That is 'Frustrum Clipping' of points outside of the camera's view volume (not whether or not the point is 'obscured' within the view).

            For what you're trying to do, you'll need to do both backface culling (points on polygons facing away from the camera) and, worse, hidden surface determination (points on polygons obscured by other polygons).

            I don't know what facilities are available for these tasks in the SDK, but I'll have a gander and see! 🙂

            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 01/10/2005 at 17:53, xxxxxxxx wrote:

              Howdy,

              I did another search and found this thread about the same thing:
              Visible Point Question
              It seems that I need to look into the GeRayCollider class.

              Adios,
              Cactus Dan

              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 01/10/2005 at 18:00, xxxxxxxx wrote:

                That looks like the best bet. I was going to suggest VolumeData::TraceGeometry() which uses a Ray for hit determination - but it looked more for raytracing than general 3D work.

                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 03/10/2005 at 10:01, xxxxxxxx wrote:

                  Howdy,

                  OK, I'm a little confused working with the GeRayCollider. I've got it working but it's only working when the object's matrix is the identity matrix (object at world 0,0,0).

                  Here is the code:

                  Bool TestTool::MouseInput(BaseDocument *doc, BaseContainer &data;, BaseDraw *bd,EditorWindow *win, const BaseContainer &msg;)  
                  {  
                       BaseObject     *opActive = doc->GetActiveObject();  
                       if (!opActive->IsInstanceOf(Opoint)) return TRUE;  
                    
                       Vector     rayDir, rayPt, rayEnd, rayStart, opt, mpt, *padr = ToPoint(opActive)->GetPoint();  
                       LONG     index, ptCount = ToPoint(opActive)->GetPointCount();  
                    
                       mx = msg.GetReal(BFM_INPUT_X);  
                       my = msg.GetReal(BFM_INPUT_Y);  
                       LONG button;  
                         
                       switch (msg.GetLong(BFM_INPUT_CHANNEL))  
                       {  
                            case BFM_INPUT_MOUSELEFT : button=KEY_MLEFT; break;  
                            case BFM_INPUT_MOUSERIGHT: button=KEY_MRIGHT; break;  
                            default: return TRUE;  
                       }  
                         
                       AutoAlloc<GeRayCollider> rc;  
                       if (!rc) return FALSE;  
                       rc->Init(opActive, TRUE);  
                    
                       Real                    dx, dy, rad=10.0;  
                       mDrag = FALSE;  
                       BaseContainer bc, device;  
                       BaseSelect *bs = ToPoint(opActive)->GetPointS(); if (!bs) return TRUE;  
                       win->MouseDragStart(button,mx,my,MOUSEDRAG_DONTHIDEMOUSE|MOUSEDRAG_NOMOVE);  
                       while (win->MouseDrag(&dx;,&dy;,&device;)==MOUSEDRAG_CONTINUE)  
                       {  
                            mx+=dx;  
                            my+=dy;  
                            mDrag = TRUE;  
                            for(index=0; index<ptCount; index++)  
                            {  
                                 opt = bd->WS(opActive->GetMg() * padr[index]);  
                                 opt.z = 0.0;  
                                 mpt.x = mx;  
                                 mpt.y = my;  
                                 mpt.z = 0.0;  
                                 if(Len(opt - mpt) < rad)  
                                 {  
                                      rayEnd = bd->SW(Vector(mx,my,0));  
                                      rayStart = bd->SW(Vector(mx,my,10000.0));  
                                      rayDir = (opActive->GetMg()) * (rayEnd - rayStart);  
                                      rayPt = (opActive->GetMg() * padr[index]) + !rayDir*0.1;  
                                      if(!rc->Intersect(rayPt, rayDir, 10000.0))  
                                      {  
                                            bs->Select(index);  
                                      }  
                                      else GePrint("Intersections = "+LongToString(rc->GetIntersectionCount()));  
                                 }  
                            }  
                            DrawViews(DA_ONLY_ACTIVE_VIEW|DA_NO_THREAD|DA_NO_ANIMATION);  
                       }  
                       mDrag = FALSE;  
                       DrawViews(DA_ONLY_ACTIVE_VIEW|DA_NO_THREAD|DA_NO_ANIMATION);  
                    
                       return TRUE;  
                  }
                  

                  The SDK docs say that rayPt and the rayDir need to be in "object coordinates" so I also tried these lines:

                    
                                      rayDir = (!opActive->GetMg()) * (rayEnd - rayStart);  
                                      rayPt = (!opActive->GetMg() * padr[index]) + !rayDir*0.1;  
                  

                  But, that doesn't make any difference. It still only works if the object is at the origin. How do I ensure that the rayPt and rayDir are in "object coordinates"?

                  Adios,
                  Cactus Dan

                  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 10/10/2005 at 07:12, xxxxxxxx wrote:

                    Howdy,

                    Well, all I can say is DOH! 😞

                    This is the way to do it:

                      
                                        rayDir = (!opActive->GetMg()) * (rayEnd - rayStart);  
                                        rayPt = padr[index]) + !rayDir*0.1;  
                    

                    The points array is already in "object coordinates" so it doesn't need converting.

                    Adios,
                    Cactus Dan

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