Jump to content

How can I calculate curve normal?


Recommended Posts

Hi, houdini dev guys!

I am studying hdk and implementing a basic sop. It is similar with polyframe sop.

Now I am stuck with calculate average normal on a curve.(like facet sop) There should be a method for this. I find some calculateNormal functions on here and there. But I couldn't figure out which is one and how can I apply it.

So, please help me. General advise are also welcome!

Thank you. :)


// calculate curve's tangent or N

...

OP_ERROR
CurveAttrib::cookMySop(OP_Context &context)
{

if (lockInputs(context) >= UT_ERROR_ABORT)
return error();

duplicateSource(0, context);

GA_WOAttributeRef tangentRef;
tangentRef = gdp->addFloatTuple(GA_ATTRIB_POINT, "tangent", 3);
const GA_AIFTuple *tangentAIF = tangentRef.getAIFTuple();
GA_RWHandleV3 Phandle(gdp->findAttribute(GA_ATTRIB_POINT, "P"));
GEO_Primitive *prim;
GEO_AttributeHandle gah;
GA_FOR_ALL_PRIMITIVES(gdp, prim)
{
GA_Range ptrange = prim->getPointRange();
GA_Size npt = prim->getVertexCount()-1;
GA_Offset lastpt = prim->getPointOffset(npt);
GA_Offset firstpt = prim->getPointOffset(0);

bool curve_is_closed = false;
fpreal area = prim->calcArea();
if (!SYSalmostEqual(area, 0.0)) {
curve_is_closed = true;
}
for (GA_Iterator iterpt(ptrange.begin()); !iterpt.atEnd(); ++iterpt)
{
GA_Offset ptoff = iterpt.getOffset();
UT_Vector3 tangent;
UT_Vector3 Pcurr;
UT_Vector3 Pnext;
if ((ptoff==lastpt) && curve_is_closed) {
Pnext = Phandle.get(firstpt);
Pcurr = Phandle.get(ptoff);
tangent = Pnext-Pcurr; //circular
}
else if ((ptoff==lastpt) && !curve_is_closed) {
Pnext = Phandle.get(ptoff-1);
Pcurr = Phandle.get(ptoff);
tangent = Pcurr-Pnext; //backward
}
else {
Pnext = Phandle.get(ptoff+1);
Pcurr = Phandle.get(ptoff);
tangent = Pnext-Pcurr;
}
tangent.normalize();
tangentAIF->set(tangentRef.getAttribute(), ptoff, tangent.data(), 3);
}
}
gdp->notifyCache(GU_CACHE_ALL);
unlockInputs();
return error();
}
[/CODE]

Link to comment
Share on other sites

  • 10 months later...

I'll bump this up, because i'm doing the same thing right now  :)  To get an average normal for curve, you can use GU_Curve class method curveNormal(). Getting GU_Curve is a little bit tricky:

GEO_Primitive *_prim = gdp->getGEOPrimitive(0);
GEO_Curve *geocurve = static_cast<GEO_Curve*>(_prim);
((GU_Curve *)geocurve->castTo())->curveNormal(out);

Now, my question is: Is there any method/class to compute tangent and bitangent vectors like polyframe sop does?

Link to comment
Share on other sites

Ok, never mind. It looks like it pretty simple. Here is how it's done in Polyframe SOP: 

Tangent vector = Prev. point position - Next point position

Bitangent vector = cross ( Tangent, Curve average normal)

 

P.s. doing some interesting stuff. More question to come. )

Link to comment
Share on other sites

Hi, Stalkerx777.

 

Thank you for answer for this!

 

But I am really a C++ primer. So, all the type conversions break my head. :(

 

I have questions about the conversions.

 

1. How can I sure the static_cast (GEO_Primitive to GEO_Curve) is safe? I've heard static_casting base class to derived class may somewhat unsafe.

 

2. Why did you use castTo() method for GEO_Curve to GU_Primitive? It seems they don't make any relationship in perspective of class hierarchy. Is it possible to conversion?

 

3. Why did you use (GU_Curve *) instead of static_cast<GU_Curve *>, although (GU_Primitive -> GU_Curve) looks similar to (GEO_Primitive -> GEO_Curve).

 

It is hard to understand about C++ conversion even if I've read some documents about type conversion on web. (In C++, usually class hierarchy is too big and have so many conversion methods!)

 

Thanks in advance!

Edited by yongbin
Link to comment
Share on other sites

I'm not a c++ programmer, so sometimes i try a lot of things, before something get to work. :) Same with casting. One is old C style, other is c++ style.

((GU_Curve *)geocurve->castTo())->curveNormal(out);

I'm also not able to cast this into a variable. But i'm not tried this whit static_cast.. Maybe it works. castTo() is a special method to get GU_* type classed from GEO_*.

Try to google on c++ type casting. There is a lot of good articles.

http://msdn.microsoft.com/en-us/library/c36yw7x9.aspx

Edited by Stalkerx777
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...