# How can I calculate curve normal?

## Recommended Posts

yongbin    20

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.

Thank you.

`// calculate curve's tangent or N...OP_ERRORCurveAttrib::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]`

##### Share on other sites

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?

##### 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. )

##### Share on other sites
yongbin    20

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!)

Edited by yongbin

##### 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

##### Share on other sites
yongbin    20

The page looks like a great article! I will look into it!