Solve the viewportdraw display problem of ARX custom object class

Source: Internet
Author: User

Problem description:

The view-related display is drawn in the viewportdraw of the custom object. Why is the display not displayed when 3 dorbit (3D Dynamic Observation) is run? Is the display normal after 3 dorbit is exited?

After repeated tests, after a user-defined object is created, as long as the User-Defined Object attribute modification function is called, the corresponding object will not be displayed when running the 3dorbit command.

Issue

Our custom entity does all its drawing in the viewportdraw routine, but if you display one of our entities on a 'shademode' view (hide/flat/Gouraud etc .) then the entity does not appear. changing back to 2D displays the entity properly. why doesn't our entity display properly in shademode?

Solution

There are several problems related to this issue which make this a difficult area to develop with. These problems are present in AutoCAD 2000i, 2002,200 4, 2005,200 6 and 2007 but not in r2000.

Here is a summary of them, and a brief description of each workaround, which is demonstrated below:

1) if graphics are created from within viewportdraw () (ie worlddraw () returns false), The kdrawableviewindependentviewportdraw flag must be set within setattributes () in order to see any custom entity graphics when in a shademode other than 2D wireframe. this applies not only for viewport-independent graphics, but also for viewport-dependent graphics. this is related to change request 282888 and has been fixed for AutoCAD 2004 upwards.

2) When in a shademode other than 2D wireframe, viewportdraw () will be called with the incorrect regentype () intermittently, so that when zooming or panning (among other operations ), the graphics will appear to switch at random. this is change request 168103. A workaround to determine the regentype () manually can be implemented by simply trying to create an acgsview with acgsgetgsview (), which will fail in 2D shademode, but succeed in any other mode.

Note that acgsgetgsview () is part of the ObjectARX SDK (not objectdbx) and therefore care shocould be taken to get the module handle of acad.exe then get proc address-don't link your DBX to the ObjectARX SDK (see code below)

3) when in a shademode other than 2D wireframe, acgiviewportdraw: viewdir () will always return (0, 0, 1) when the regentype () is kacgirendercommand (which again is intermittent ). the view direction must be calculated via acgsview: Position () and acgsview: Target (). see Code workaround below. this is change request 136908.

4) if while in shademode the graphics representation is changed (eg from 3d to 2D or vice versa), the 3D graphics queue must be flushed. even a regen command will not always update these graphics, but acgsview: invalidatecachedviewportgeometry () (or acgsmodel: invalidate () Does this properly. this is not necessary when shademode is 2D wireframe. this is by design, but is not well formed ented.

Solution to problem 1 (CODE)

// Within the custom entity, add the kdrawableviewindependentviewportdraw flag
// The base-class version of setattributes ()...
Adesk: uint32 Cline: setattributes (acgidrawabletraits * ptraits)
{
Return acdbentity: setattributes (ptraits) | kdrawableviewindependentviewportdraw;
}

Solution to problem 2 (CODE)

 

// Tries to get the gsview from AutoCAD. It's fine to do this in non AutoCAD
// Applications because if AutoCAD doesn't exist, we simply don't do anything
Acgsview * getgsview (acgiviewportdraw * Mode)
{
// See if we are running inside of AutoCAD
Hmodule hmod =: getmodulehandle (_ T ("acad.exe "));
// If we are
If (hmod)
{
// Prepare a function pointer to get the acgsview.
Typedef acgsview * (* exp_acgsgetgsview) (INT, bool );
// Try to get the function pointer to acgsgetgsview
Exp_acgsgetgsview funcptr = (exp_acgsgetgsview): getprocaddress (hmod ,"? Acgsgetgsview @ yapavacgsview @ h_n @ Z ");
// If this was successful, we can assume that we can use it.
If (funcptr)
// All OK, return the acgsview
Return funcptr (Mode-> viewport (). acadwindowid (), false );
}

Return NULL;
}

Solution to problem 3 (CODE)

// Function to determine the view direction.
Acgevector3d getviewdirection (acgiviewportdraw * Mode)
{
// Try and extract the acgsview
Acgsview * pview = getgsview (mode );
// If OK and in 3D view-we must calc our own view direction
If (pview)
// If 3D view, then we must calc our own...
Return (pview-> position ()-pview-> Target (). normalize ();
Else
// Otherwise, the viewdir must be OK
Return mode-> viewport (). viewdir (). normalize ();
}

 

// Here is the overridden viewportdraw () which provided des the remaining workarounds...
Void Cline: viewportdraw (acgiviewportdraw * Mode)
{
// Try to obtain an acgsview for the current viewport... This will fail if it is a 2D wireframe (normal) view or if not running in AutoCAD
// (Will set pview to null .)
Acgsview * pview = getgsview (mode); // This will solve problem 2
// You can detect if there is a conflict (ie the defect is present) like this:
If (pview & mode-> regentype () = kacgistandarddisplay)
Acutprintf ("Conflict in regen type ");

// This is to workaround change request 136908... the viewdir is incorrect for regentype krendercommand...
// We can calculate the view direction ourselves for a 3D view ..
Acgevector3d vdir = getviewdirection (mode); // This will solve problem 3

// Draw your graphics here... perhaps they are drawn differently depending on 2D or 3D modes...


// You must invalidate the 3D graphics cache if your graphics change between 2D and 3D modes.
// Perhaps this can be done within an editor reactor which detects when the shademode
// Command ends, and place the call to invalidatecachedviewportgeometry () There, but of course
// That wowould require ObjectARX. Instead you can place the following code in the viewportdraw ()
// Function, note that it will cause the function to be called twice anytime an update is needed
// (This may be a small price to pay however ).

If (pview)
{
Pview-> invalidatecachedviewportgeometry (); // This will solve problem 4

// The following code also works for this purpose:
// Acgsmodel * gsmodel = acgsgetgsmanager ()-> getdbmodel ();
// Gsmodel-> invalidate (acgsmodel: kinvalidateviewportcache );
}

Thank you for the help of the Sea (7098676) and a stay (15983527!

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.