文档的范围
•C/C++
•GLSL 程序
•OpenCL 内核
•TCL 脚本和测试用例
命名约定
一般命名规则
国际语言 [强制性]
有意义的名称
•包含单词 Geom 或 Geom2d 的包与几何数据和操作有关。
•包含单词 TopoDS 或 BRep 的包与拓扑数据和操作有关。
•以 ...Test 结尾的包定义了 Draw Harness 插件。
•以 Get... 和 Set... 开头的方法通常分别负责检索和存储数据。
相关名称
驼峰式大小写
Standard_Integer awidthofbox; // this is badStandard_Integer width_of_box; // this is badStandard_Integer aWidthOfBox; // this is OK
开发单元的名称
单元名称中不使用下划线 [强制性]
文件扩展名 [强制性]
•.cxx – C++ 源文件
•.hxx – C++ 头文件
•.lxx – 包含内联方法定义和辅助代码的附加头文件
工具包名称的前缀 [强制性]
工具包名称应以前缀 TK 开头,后面跟着一个有意义的部分,解释工具包所涵盖的功能领域(例如 TKOpenGl)。
公共类型的名称
<package-name>_<class-name>
typedef NCollection_IndexedDataMap<TCollection_AsciiString,TCollection_AsciiString,TCollection_AsciiString> TColStd_IndexedDataMapOfStringString;函数名称
• 任何类方法
• 任何包方法
• 任何非成员过程或函数
class MyPackage_MyClass{public:Standard_Integer Value() const;void SetValue (const Standard_Integer theValue);private:void setIntegerValue (const Standard_Integer theValue);};
变量名称
变量命名
Standard_Integer Elapsed_Time = 0; // this is bad - possible class nameStandard_Integer gp = 0; // this is bad - existing package nameStandard_Integer aGp = 0; // this is OKStandard_Integer _KERNEL = 0; // this is badStandard_Integer THE_KERNEL = 0; // this is OK
函数参数名称
void Package_MyClass::MyFunction (const gp_Pnt& p); // this is badvoid Package_MyClass::MyFunction (const gp_Pnt& theP); // this is OKvoid Package_MyClass::MyFunction (const gp_Pnt& thePoint); // this is preferred
类成员变量名称
Standard_Integer counter; // This is badStandard_Integer myC; // This is OKStandard_Integer myCounter; // This is preferred
全局变量名称
Standard_Integer MyPackage_myGlobalVariable = 0;Standard_Integer MyPackage_MyClass_myGlobalVariable = 0;
文件内的静态常量应使用大写字母编写,并以前缀 THE_ 开头:
namespace{static const Standard_Real THE_CONSTANT_COEF = 3.14;};
局部变量名称
Standard_Integer theI; // this is badStandard_Integer i; // this is badStandard_Integer index; // this is badStandard_Integer anIndex; // this is OK
避免使用虚拟名称
避免使用虚拟名称,如 i、j、k。这样的名称没有意义,且容易混淆。
当多次使用这样的虚拟名称时,代码变得越来越复杂,或者在不同的迭代范围内使用时,等等。
以下是首选风格的一些示例:
void Average (const Standard_Real** theArray,Standard_Integer theRowsNb,Standard_Integer theRowLen,theResult){theResult = 0.0;for (Standard_Integer aRow = 0; aRow < aRowsNb; ++aRow){for (Standard_Integer aCol = 0; aCol < aRowLen; ++aCol){theResult += theArray[aRow][aCol];}theResult /= Standard_Real(aRowsNb * aRowLen);}}
格式化规则
为了提高开源代码的可读性,从而提高可维护性,以下是应用的一组规则。
国际语言 [强制性]
所有源代码中的注释必须使用英文。
行长度
尽量在所有源代码中保持每行120个字符的限制。
C++风格注释
在 C++ 源代码中,推荐使用 C++ 风格的注释。
注释掉未使用的代码
删除未使用的代码,而不是注释掉或使用 #define。
源代码中的缩进 [强制性]
所有源代码的缩进应设置为两个空格字符。禁止使用制表符字符进行缩进。
分隔空格
标点规则遵循英语语言的规则。
•C/C++ 保留字、逗号、冒号和分号后面如果不是行尾,应跟一个空格字符。
•'(' 后面和 ')' 前面不应有空格字符。闭合和开放括号之间应有一个空格字符。
•为了更好的可读性,还建议在常规运算符周围加上一个空格字符。例如:
在布尔表达式中,建议在逻辑运算符周围使用空格:
while (true) // NOT: while( true ) ...{DoSomething (theA, theB, theC, theD); // NOT: DoSomething(theA,theB,theC,theD);}for (anIter = 0; anIter < 10; ++anIter) // NOT: for (anIter=0;anIter<10;++anIter){{theA = (theB + theC) * theD; // NOT: theA=(theB+theC)*theD}
指针和引用的声明
Standard_Integer *theVariable; // not recommendedStandard_Integer * theVariable; // not recommendedStandard_Integer* theVariable; // this is OKStandard_Integer *&theVariable; // not recommendedStandard_Integer *& theVariable; // not recommendedStandard_Integer*& theVariable; // this is OKStandard_Integer **theVariable; // not recommendedStandard_Integer ** theVariable; // not recommendedStandard_Integer** theVariable; // this is OKStandard_Integer *theA, theB, **theC; // not recommended (declare each variable independently)
分隔逻辑块
// check argumentsStandard_Integer anArgsNb = argCount();if (anArgsNb < 3 || isSmthInvalid){return THE_ARG_INVALID;}// read and check header......// do our job......
注意应避免使用多个空行。
分隔函数体 [强制性]
// =======================================================================// function : TellMeSmthGood// purpose : Gives me good news// =======================================================================void TellMeSmthGood(){...}// =======================================================================// function : TellMeSmthBad// purpose : Gives me bad news// =======================================================================void TellMeSmthBad(){...}
代码块布局 [强制性]
while (expression){...}
单行操作符
if (!myIsInit) return Standard_False; // badif (thePtr == NULL) // OKreturn Standard_False;if (!theAlgo.IsNull()) // preferred{DoSomething();}
常量比较表达式
if (NULL != thePointer) // Yoda style, not recommendedif (thePointer != NULL) // OKif (34 < anIter) // Yoda style, not recommendedif (anIter > 34) // OKif (theNbValues >= anIter) // bad style (constant function argument vs. local variable)if (anIter <= theNbValues) // OKif (THE_LIMIT == theValue) // bad style (global constant vs. variable)if (theValue == THE_LIMIT) // OK
对齐
MyPackage_MyClass anObject;Standard_Real aMinimum = 0.0;Standard_Integer aVal = theVal;switch (aVal){case 0: computeSomething(); break;case 12: computeSomethingElse (aMinimum); break;case 3:default: computeSomethingElseYet(); break;}
注释的缩进
while (expression) //bad comment{// this is a long multi-line comment// which is really requiredDoSomething(); // maybe, enoughDoSomethingMore(); // again}
早期返回语句
Standard_Integer ComputeSumm (const Standard_Integer* theArray,const Standard_Size theSize){Standard_Integer aSumm = 0;if (theArray == NULL || theSize == 0){return 0;}... computing summ ...return aSumm;}
Standard_Integer ComputeSumm (const Standard_Integer* theArray,const Standard_Size theSize){Standard_Integer aSumm = 0;if (theArray != NULL && theSize != 0){... computing summ ...}return aSumm;}
尾随空格
头文件顺序
// the header file of implemented class// OCCT headers// Qt headers// system headers
文档规则
•注释易于获取 - 它们总是与源代码一起;
•在源代码修改时,很容易更新注释中的描述;
•源代码本身是描述各种细节的好上下文,这些细节在单独的文档中需要更多的解释;
•总之,这是最具成本效益的文档。
记录类 [强制性]
记录类方法 [强制性]
//! Method computes the square value.//! @param theValue the input value//! @return squared valueStandard_Export Standard_Real Square (Standard_Real theValue);
记录 C/C++ 源代码
应用程序设计
允许可能的继承
避免友元声明
设置/获取方法
隐藏虚拟函数 [强制性]
避免混合错误报告策略
最小化编译器警告 [强制性]
在编译源代码时注意并尽量最小化编译器警告。
避免不必要的包含
通用 C/C++ 规则
包装全局变量 [强制性]
避免私有成员
常量和内联函数超过定义 [强制性]
避免显式数值 [强制性]
三个强制性方法
虚拟析构函数
覆盖虚拟方法
class MyPackage_BaseClass{public:Standard_EXPORT virtual Standard_Boolean Perform();};class MyPackage_MyClass : public MyPackage_BaseClass{public:Standard_EXPORT virtual Standard_Boolean Perform() Standard_OVERRIDE;};
默认参数值
不要在继承的函数中重新定义默认参数值。
使用 const 修饰符
尽可能地使用 const 修饰符(函数参数、返回值等)。
使用 goto 的情况 [强制性]
除非真的需要,否则避免使用 goto 语句。
在 for() 头声明变量
Standard_Real aMinDist = Precision::Infinite();for (NCollection_Sequence<gp_Pnt>::Iterator aPntIter (theSequence);aPntIter.More(); aPntIter.Next()){aMinDist = Min (aMinDist, theOrigin.Distance (aPntIter.Value()));
零值条件语句
void Function (Standard_Integer theValue,Standard_Real* thePointer){if (!theValue) // bad style - ambiguous logic{DoSome();}if (theValue == 0) // OK{DoSome();}if (thePointer != NULL) // OK, predefined NULL makes pointer comparison cleaner to reader{ // (nullptr should be used instead as soon as C++11 will be available)DoSome2();}}
可移植性问题
提供代码可移植性 [强制性]
避免使用全局变量 [强制性]
避免显式使用基本类型
使用 sizeof() 计算大小 [强制性]
文件末尾的空行 [强制性]
稳定性问题
使用 OSD::SetSignal() 捕获异常
交叉引用的句柄
class Slave;class Master : public Standard_Transient{...void SetSlave (const Handle(Slave)& theSlave){mySlave = theSlave;}...private:Handle(Slave) theSlave; // smart pointer...}class Slave : public Standard_Transient{...void SetMaster (const Handle(Master)& theMaster){myMaster = theMaster.get();}...private:Master* theMaster; // simple pointer...}
C++ 内存分配
匹配 new 和 delete [强制性]
aPtr1 = new TypeA[n]; ... ; delete[] aPtr1;aPtr2 = new TypeB(); ... ; delete aPtr2;aPtr3 = Standard::Allocate (4096); ... ; Standard::Free (aPtr3);
管理动态分配的方法 [强制性]
未初始化变量 [强制性]
Standard_Integer aTmpVar1; // badStandard_Integer aTmpVar2 = 0; // OK
不要隐藏全局 new
赋值运算符
浮点数比较
if (Abs (theFloat1 - theFloat2) < theTolerance){DoSome();}
•Precision::Confusion() 用于以米为单位的长度;
•Precision::Angular() 用于以弧度为单位的角度。
•Precision::Infinite()
•Precision::IsInfinite()
•Precision::IsPositiveInfinite()
•Precision::IsNegativeInfinite()
非索引迭代
不要在析构函数中抛出异常
赋值给引用 [强制性]
性能问题
类字段对齐
字段初始化顺序 [强制性]
class MyPackage_MyClass{public:MyPackage_MyClass(): myPropertyA (1),myPropertyB (2) {}// NOT// : myPropertyB (2),// myPropertyA (1) {}private:Standard_Integer myPropertyA;Standard_Integer myPropertyB;};
初始化优于赋值
MyPackage_MyClass(): myPropertyA (1) // preferred{myPropertyB = 2; // not recommended}
优化缓存
Standard_Real anArray[4096][2];for (Standard_Integer anIter = 0; anIter < 4096; ++anIter){anArray[anIter][0] = anArray[anIter][1];}
Standard_Real anArray[2][4096];for (Standard_Integer anIter = 0; anIter < 4096; ++anIter){anArray[0][anIter] = anArray[1][anIter];}
Draw Harness 命令
返回值
验证输入参数
验证输入参数的数量
if (theArgsNb != 3){std::cout << "Syntax error - wrong number of arguments!\n";return 1;}Standard_Integer anArgIter = 1;Standard_CString aResName = theArgVec[anArgIter++];Standard_CString aFaceName = theArgVec[anArgIter++];TopoDS_Shape aFaceShape = DBRep::Get (aFaceName);if (aFaceShape.IsNull()|| aFaceShape.ShapeType() != TopAbs_FACE){std::cout << "Shape " << aFaceName << " is empty or not a Face!\n";return 1;}DBRep::Set (aResName, aFaceShape);return 0;
消息打印
参数列表
myCommand -flag1 value1 value2 -flag2 value3参数解析器
• 整数值应使用 Draw::Atoi() 函数读取。
• 实数值应使用 Draw::Atof() 函数读取。
• 标志名称应以不区分大小写的方式检查。
Standard_Real aPosition[3] = {0.0, 0.0, 0.0};for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter){Standard_CString anArg = theArgVec[anArgIter];TCollection_AsciiString aFlag (anArg);aFlag.LowerCase(); //!< for case insensitive comparisonif (aFlag == "position"){if ((anArgIt + 3) >= theArgsNb){std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";return 1;}aPosition[0] = Draw::Atof (theArgVec[++anArgIt]);aPosition[1] = Draw::Atof (theArgVec[++anArgIt]);aPosition[2] = Draw::Atof (theArgVec[++anArgIt]);}else{std::cout << "Syntax error! Unknown flag '" << anArg << "'\n";return 1;}}
示例
示例记录类
class Package_Class{public: //! @name public methods//! Method computes the square value.//! @param theValue the input value//! @return squared valueStandard_Export Standard_Real Square (const Standard_Real theValue);private: //! \@name private methods//! Auxiliary methodvoid increment();private: //! \@name private fieldsStandard_Integer myCounter; //!< usage counter};// ==========================================================// function : Square// purpose : Method computes the square value// ==========================================================Standard_Real Package_Class::Square (const Standard_Real theValue){increment();return theValue * theValue;}// ==========================================================// function : increment// purpose :// ==========================================================void Package_Class::increment(){++myCounter;}
Draw Harness 的 TCL 脚本
1 # show fragments (solids) in shading with different colors2 proc DisplayColored {theShape} {3 set aSolids [uplevel #0 explode $theShape so]4 set aColorIter 05 set THE_COLORS {red green blue1 magenta1 yellow cyan1 brown}6 foreach aSolIter $aSolids {7 uplevel #0 vdisplay $aSolIter8 uplevel #0 vsetcolor $aSolIter [lindex $THE_COLORS [expr [incr aColorIter] % [llength $THE_COLORS]]]9 uplevel #0 vsetdispmode $aSolIter 110 uplevel #0 vsetmaterial $aSolIter plastic11 uplevel #0 vsettransparency $aSolIter 0.512 }13 }1415 # load modules16 pload MODELING VISUALIZATION1718 # create boxes19 box bc 0 0 0 1 1 120 box br 1 0 0 1 1 221 compound bc br c2223 # show fragments (solids) in shading with different colors24 vinit View125 vclear26 vaxo27 vzbufftrihedron28 DisplayColored c29 vfit30 vdump $imagedir/${casename}.png 512 512
GLSL 程序:
vec3 Ambient; //!< Ambient contribution of light sourcesvec3 Diffuse; //!< Diffuse contribution of light sourcesvec3 Specular; //!< Specular contribution of light sources//! Computes illumination from light sourcesvec4 ComputeLighting (in vec3 theNormal,in vec3 theView,in vec4 thePoint){// clear the light intensity accumulatorsAmbient = occLightAmbient.rgb;Diffuse = vec3 (0.0);Specular = vec3 (0.0);vec3 aPoint = thePoint.xyz / thePoint.w;for (int anIndex = 0; anIndex < occLightSourcesCount; ++anIndex){int aType = occLight_Type (anIndex);if (aType == OccLightType_Direct){directionalLight (anIndex, theNormal, theView);}else if (aType == OccLightType_Point){pointLight (anIndex, theNormal, theView, aPoint);}}return vec4 (Ambient, 1.0) * occFrontMaterial_Ambient()+ vec4 (Diffuse, 1.0) * occFrontMaterial_Diffuse()+ vec4 (Specular, 1.0) * occFrontMaterial_Specular();}//! Entry point to the Fragment Shadervoid main(){gl_FragColor = computeLighting (normalize (Normal),normalize (View),Position);}

想了解更多
赶紧扫码关注
版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.bianchenghao6.com/h6javajc/26380.html