Basic Objects
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 08/05/2008 at 02:46, xxxxxxxx wrote:
After a little bit of coding and C&P; of Code from AtomObject.cpp i managed to a) create a polygon object with n vertex and m faces, but the faces aren't visible somehow.
b) create a single sphere primitive, but its subdivision or lod values are not changing the objects appearance.At first: What is the difference between *BuildPolgonHull(...) creating primitives and *BuildIsoHull(...) creating a LineObject.
Second: How can I transform an object from parametrical into polygonal? With toPoly() ?
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 08/05/2008 at 10:14, xxxxxxxx wrote:
Hopefully, you've set up the vertices values (for a sphere) and set up the polygon indices (a,b,c,d) to point to the proper vertices by index in the Vector array. You should call obj->Message(MSG_UPDATE) after doing this setup.
The sphere primitive subdivision or lod only apply to the sphere primitive object. There can be no effect on the polygon object without direct intervention (you, that is).
BuildPolyHull() and BuildIsoHull() are what the Atom object in the examples is using to build the objects to represent the atom. These are probably a bit more complex than your needs since you are only interested in building a single object. I wouldn't worry about the BuildIsoHull() at all.
ToPoly() only changes the pointer type. To make an object polygonal (when possible) you need to use SendModelingCommand(MCOMMAND_CURENTSTATETOOBJECT). I don't think you should be doing this in a generator object's GetVirtualObject() method, though.
My thoughts here:
1. You could just use a tag plugin attached to a regular sphere primitive which sets the sphere primitive segments depending upon some calculation of the distance of the sphere from the current camera. Now you have a sphere with LOD. This is what makes tags so useful - we can't modify or augment existing object types in C4D, but we can do this (to some extent) with plugin tags. In some sense, the same is true of generator and modifier object plugins as well - but their purposes are more explicit.
2. If you are determined to go the generator object route, it may require that there is a child object (or not - not certain if GetVirtualObjects() is somehow not triggered without a child present). You should either just create a primitive sphere and do the LOD for its segments or just create a polygon object and set it up with the calculated vertices dependent upon the LOD. You can't convert the primitive into a polygon object while in GetVirtualObjects() as best I can tell (see this
discussion). -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 09/05/2008 at 01:59, xxxxxxxx wrote:
Thank you for some clearing thoughts.
Uhm, well I haven't set vertice values or poly indices yet. I just found out that PolygonObject::Alloc(6,5); allocates 6 Points and 5 Faces. I have to look at this in the examples to set up vertice values and poly indices. Thx for this clue I am sure, GetVirtualObjects is triggered without a given child. My result has been 6 Points in the object's center.About the tag: I just cannot imagine, that this type would fit my needs. The LOD I wan't to apply if the category CLOD and therefore mustn't be uniform throught the whole mesh, so two basics have to be fulfilled: a poly mesh is built up from scrap using triangle faces (for further refinement/coarsing). Refinement may be possible with mid-edge cutting, coarsing with merging vertexpoints. Perhaps I am running into a dead end with this idea, but in theory it is possible. (A directX C#/.NET prototype of this is already existing)
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 09/05/2008 at 08:44, xxxxxxxx wrote:
Yep. You'll need to make some initial estimate or use a stock amount of points and polygons on the initial Alloc() but you can update these using VariableChanged (see the SDK docs for more details about using it) while you do your CLOD calculations.
I see. For something like this, a generator object may be best then. I would create the 'unformed' PolygonObject, set it up initially to the average or lowest subdivision of the sphere for the LOD, and then do the finer CLOD work. All of this can be done in GetVirtualObjects() - or using calls from there like the AtomObject uses with BuildPolyHull().
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 09/05/2008 at 09:09, xxxxxxxx wrote:
I planned to start from a sphere with a radius x and a segment count of 4 (representing an octa).
But I have serious problems building up this quite simple object.
GetVirtualObject() calls the Recurse() function, which calls the BuildPolyHull(). My probs are to extract the necessary items from the Recurse(), resulting in a crash of C4D, since the recurse requires an polygonized input object, etc. Right now I am overwhelmed by the complexity of the atom.cpp.But thanks to you for your patience so far
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 13/05/2008 at 08:20, xxxxxxxx wrote:
I think I figured out how the object is built. However no object is created and inserted into the scene.
What went wrong ?
>
class GenerateObject : public CommandData \> { \> public: \> virtual Bool Execute(BaseDocument \*doc, HierarchyHelp \*hierarchyHelper); \> }; \> \> PolygonObject \*CreatePolygonObject(BaseDocument \*doc, HierarchyHelp \*hierarchyHelper) \> { \> BaseContainer baseContainer; \> LONG vCnt,pCnt; \> const Vector \*vArr=NULL; \> const CPolygon \*pArr = NULL; \> Vector \*vertexArr = NULL; \> CPolygon \*polyArr = NULL; \> \> \> BaseThread \*baseThread=hierarchyHelper->GetThread(); \> \> \> baseContainer.SetReal(SPHEREOBJECT_RAD,100.0); \> baseContainer.SetLong(SPHEREOBJECT_SEG,4); \> \> \> PolygonObject \*sphere = (PolygonObject\* )GeneratePrimitive(doc,Osphere,baseContainer,4,FALSE,baseThread); \> if(!sphere){ \> blDelete (sphere); \> return NULL; \> } \> \> vCnt = sphere->GetPointCount(); \> pCnt = sphere->GetPolygonCount(); \> vArr = sphere->GetPointR(); \> pArr = sphere->GetPolygonR(); \> \> AutoAlloc<PolygonObject> polyObject(vCnt,pCnt); \> if(!polyObject){ \> return NULL; \> } \> \> for(LONG i=0;i<vCnt;i++) \> { \> vertexArr[i]= vArr[i]; \> for(LONG j=0;j<pCnt;j++) \> { \> polyArr[j] = CPolygon(pArr[j].a,pArr[j].b,pArr[j].c); \> } \> } \> \> return polyObject; \> } \> \> \> Bool GenerateObject::Execute(BaseDocument \*doc, HierarchyHelp \*hierarchyHelper){ \> PolygonObject \*returnedPolyObject = CreatePolygonObject(doc, hierarchyHelper); \> return TRUE; \> } \> #define ID_GENERATEOBJECT 1022395 \> \> Bool RegisterGenerateObject(void) \> { \> // decide by name if the plugin shall be registered - just for user convenience \> String name=GeLoadString(IDS_GENERATEOBJECT); if (!name.Content()) return TRUE; \> return RegisterCommandPlugin(ID_GENERATEOBJECT,name,0,"icon.tif",String("Generate Object"), gNew GenerateObject); \> }
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 13/05/2008 at 11:08, xxxxxxxx wrote:
You can't just cast the primitive into a PolygonObject. It is a BaseObject and you'll need to make it editable before it can be used as a PolygonObject. In order to do make it editable, you will need to take the sphere primitive and use it with SendModelingCommand(MCOMMAND_MAKEEDITABLE). See this method in the docs for how to set up (similar to the first example there).
I wouldn't call blDelete(sphere) if it is NULL and instead you should call BaseObject::Free(sphere) when you delete a BaseObject so that all of the instance's resources are released.
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 14/05/2008 at 01:53, xxxxxxxx wrote:
@Robert: Actually you can cast the result of GeneratePrimitive() to a PolygonObject.
Here a very simple but complete example of a polygonal sphere generator plugin.
>
\> #include "c4d.h" \> #include "c4d_symbols.h" \> #include "oatom.h" \> \> class AtomObject : public ObjectData \> { \> public: \> virtual Bool Init(GeListNode \*node); \> virtual BaseObject\* GetVirtualObjects(PluginObject \*op, HierarchyHelp \*hh); \> \> static NodeData \*Alloc(void) { return gNew AtomObject; } \> }; \> \> // initialize settings \> Bool AtomObject::Init(GeListNode \*node) \> { \> BaseObject \*op = (BaseObject\* )node; \> BaseContainer \*data = op->GetDataInstance(); \> \> return TRUE; \> } \> \> // main routine: build virtual atom objects \> BaseObject \*AtomObject::GetVirtualObjects(PluginObject \*op, HierarchyHelp \*hh) \> { \> BaseContainer bc; \> PolygonObject \*sphere = NULL; \> sphere = (PolygonObject\* )GeneratePrimitive(NULL,Osphere,bc,1.0,FALSE,hh->GetThread()); \> \> if(!sphere) goto Error; \> \> return sphere; \> \> Error: \> blDelete(sphere); \> return NULL; \> } \> \> // be sure to use a unique ID obtained from www.plugincafe.com \> #define ID_ATOMOBJECT 1001153 \> \> Bool RegisterAtomObject(void) \> { \> // decide by name if the plugin shall be registered - just for user convenience \> String name=GeLoadString(IDS_ATOM); if (!name.Content()) return TRUE; \> return RegisterObjectPlugin(ID_ATOMOBJECT,name,OBJECT_GENERATOR,AtomObject::Alloc,"Oatom","atom.tif",0); \> } \>
cheers,
Matthias -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 14/05/2008 at 05:19, xxxxxxxx wrote:
Thanks Matthias for this simple example. This works and creates an "objected" polygon sphere. Objected means, it is a convertable object. Now I have to make this one editable, to access its vertex points and egdes.
I've tried to make this object editable with MCOMMAND_CURRENTSTATETOOBJECT and MCOMMAND_MAKEEDITABLE but getting either the result NULL or a crash.
I read it is not recommended using SendModelingCommand within GetVirtualObject since Cache is beeing rebuild by SMC. But I recognized no difference in result using it there or calling another function within GetVirtualObjects (like Bool ConvertObject(PolygonObject *sphere) ).> <code>BaseObject *GenerateObject::GetVirtualObjects(PluginObject *op, HierarchyHelp *hh)
> {
> BaseContainer bc;
> bc.SetReal(PRIM_SPHERE_RAD,100.0);
> bc.SetLong(PRIM_SPHERE_SUB,4);
> PolygonObject *sphere = (PolygonObject* )GeneratePrimitive(NULL,Osphere,bc,1.0,FALSE,hh->GetThread());
> PolygonObject *poly=NULL;
>
> ModelingCommandData mcd;
> BaseDocument *doc;
> mcd.bc = &bc;
> mcd.doc = doc;
> mcd.op = sphere;
> if(!SendModelingCommand(MCOMMAND_CURRENTSTATETOOBJECT,mcd)) return NULL;
>
> poly=static_cast<PolygonObject*>(mcd.result->GetIndex(0));
>
> if(!poly) goto Error;
> return poly;
>
> Error:
> blDelete(sphere);
> blDelete(poly);
> GePrint("no Objects");
> return NULL;
> }
> [/CODE]</code>I assume the error is cause of *doc. But doc=GetActiveDocument(); leads to a crash too. Don't know how to obtain the current open document at another way...
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 14/05/2008 at 05:25, xxxxxxxx wrote:
Well, if you want to have a polygon object you can't use a generator plugin since it always creates generators not polygon objects. In this case you have to use a tag. Maybe you can tell us what you actually want to achieve with your plugin. This would help to find a good solution.
cheers,
Matthias -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 14/05/2008 at 07:17, xxxxxxxx wrote:
In the first step, I want to create a polygonal okta (like a sphere-primitive with 4 segments). The second step is to make this object editable, so I can gain access to its polys and vertex points.
As mentioned above a CLOD-Algorithm for coarsing/refining a mesh view-dependent has to be applied on this mesh.
View-dependency is at the moment a secondary goal, primary I want to create a polygonal planet based on a given dataset. Therfor I need the vertex points and their connecting edges (building its triangles).For interested people: have look at Cloddy
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 14/05/2008 at 07:36, xxxxxxxx wrote:
If you are using a command plugin you have of course to insert the polygon object into your scene with InsertObject(). See also this thread how to create and insert objects.
cheers,
Matthias -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 14/05/2008 at 08:52, xxxxxxxx wrote:
@Matthias: Well, yeah, you can cast it as a PolygonObject* but it doesn't make it a PolygonObject instance. An Osphere doesn't have GetPolygon(), GetPoint(), etc. because it is not a PolygonObject.
@SnakeByte: If you go the tag route you might have an easier time here. You will be needing to affect a Polygon object to which the tag is attached by changing its vertices and polygons. Actually, the beauty of a tag plugin here is that you don't have to reinvent the wheel with a plugin object that works like a Polygon object - and you could generalize the CLOD to work with any Polygon object (not just spheres) either now or later.
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 14/05/2008 at 09:43, xxxxxxxx wrote:
Hey Robert
In fact, that would be great. I've thought about it some time ago. But at the moment I need to simplify it on a specific type of object (writing my Diplomathesis) and want to keep it with less user interaction. Thiswhy I am trying to create either a primitive and transfer it into polygonal state or setting up a polyobject by obtaining its vertex vectors from a primitive (seen above). And to be honest - I am a worse coder (as you might have seen ;P).
If this thesis is complete and working so far (and satisfiying my prof), I won't hesitate continuing the development in generalizing this method for all input objects using a tag.
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 14/05/2008 at 15:06, xxxxxxxx wrote:
Hmm, it seems I figured out, what is causing the crash after the MCOMMAND_CURRENTSTATETOOBJECT. The static_cast<_ANYTYPE*_>(cd.result->GetIndex(0)); leads to apllication crash, when inserting a filled object into the scene (doc->InsertObject(poly,NULL,NULL)). If I use the "old" cd.result_ex it works fine, and the current state to object creates a polygonal object of my BaseObject *sphere=BaseObject::Alloc(Osphere). I don't know what is made behind the scenes and there must be a reason why it is noted with "don't use"... So what is crap with result->GetIndex(0) that this one crashes and the "don't use" runs fine?
Cheers
Sascha -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 14/05/2008 at 17:16, xxxxxxxx wrote:
Where are you doing this - in GetVirtualObjects() or in a tag (Execute())?
Since this feature was added, I've not had trouble with this:
// +++ CurrentStateToObject
ModelingCommandData mcd;
mcd.doc = doc;
BaseContainer mbc;
mbc.SetBool(MDATA_CURRENTSTATETOOBJECT_INHERITANCE, TRUE);
mbc.SetBool(MDATA_CURRENTSTATETOOBJECT_KEEPANIMATION, FALSE);
mbc.SetBool(MDATA_CURRENTSTATETOOBJECT_NOGENERATE, FALSE);
mcd.bc = &mbc;
mcd.mode = MODIFY_ALL;
mcd.flags = 0L;
mcd.op = orig;
if (!SendModelingCommand(MCOMMAND_CURRENTSTATETOOBJECT, mcd)) return NULL;
BaseObject* proxy = static_cast<BaseObject*>(mcd.result->GetIndex(0L));
if (!proxy) return NULL;
// If the converted object is under a Null object:
// insert result
// remove converted object
// insert converted object under Figure
// remove and free result (Null)
BaseObject* op = proxy->GetDown();
if (proxy->IsInstanceOf(Onull) && op)
{
doc->InsertObject(proxy, NULL, NULL, FALSE);
op->Remove();
doc->InsertObject(op, orig, orig->GetDownLast(), FALSE);
proxy->Remove();
BaseObject::Free(proxy);
proxy = op;
}
// else, insert result under Figure
else doc->InsertObject(proxy, orig, orig->GetDownLast(), FALSE);
doc->AddUndo(UNDO_NEW, proxy);Note that the converted object in the AtomArray result may be under a Null object.
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 14/05/2008 at 17:21, xxxxxxxx wrote:
I should note that if you are converting an Osphere object into a PolygonObject, you might want to use MCOMMAND_MAKEEDITABLE instead. This doesn't require any of the mbc settings.
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 15/05/2008 at 03:35, xxxxxxxx wrote:
Hi Rob,
at the moment I am running it in ::Execute, I havent tried this in ::GetVirtualObject yet.
Debugging "result_ex" output in VC and C4D Console did not result in a memoryleak or sth else.I've used your codesample within ::Execute, which results in that nice exception
> <code>Object.cdl!CLODDY4D::Execute(BaseDocument * doc=0x05486a0c) Line 28 + 0x1f bytes C++</code>while executing
> <code>BaseObject* proxy = static_cast<BaseObject*>(mcd.result->GetIndex(0));</code>
You set mcd.flag = OL - what is this flag OL? And why you are using the "flag" in mcd.reslut->GetIndex(OL)? I replaced the flag with : MODELINGCOMMANDFLAG_CREATEUNDO;
and the Indexvalue with zero - getting the result above. this regular result says "Children cannot be evaluated".Cheers
Sascha -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 15/05/2008 at 13:50, xxxxxxxx wrote:
0L is 'zero - long value'. This just guarantees that the (LONG) flags variable is cleared.
Don't know about your crashing situation - would need to see the code or it may be that you can't do this in Execute() (?).
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 15/05/2008 at 16:13, xxxxxxxx wrote:
Using your code above does not work for me either in Execute() nor GetVirtualObjects() nor any self defined method.
I just have no idea where it comes from, perhaps because I create an object by code... but that make no sense...An further question, is it possible mcd.result_ex does not return a "real" polyobject ? I get crashes getting the Array start from the resulting poly...
I even don't get it using some terms from "roundedTube.cpp"
like
>\> BaseObject \*obj = BaseObject::Alloc(Osphere); // or any (\*obj) assigned by method call... \> PointObject \*pointObject = ToPoint(obj); \> const Vector \*pt = pointObject->GetPointR(); \>
Roundet tube is setting
>
Vector \*vector = obj->GetPointW();
But that should make no difference (for me)...
Of this usage is incorrect -> how is it used correctly with a
>PolygonObject \*obj = static_cast<PolygonObject\*>(mcd.result->GetIndex(0L))
or
>
PolygonObject \*obj = static_cast<PolygonObject\*>(mcd.result_ex)
Cheers
Sascha