Drawing arrows on atoms
-
@piriziwè For that you can use function SAMSON::displayCylinders.
So, for example, one cylinder for the line and one cylinder for the arrow head with one of the radiuses set to zero. A line may also be drawn using SAMSON::displayLines. -
Hi @Piriziwè ,
Here is an example code that you may use and that puts vertical arrows on every atom.
void SEArrowDrawerVisualModel::display() { // NodeIndexer that will receive the atoms SBNodeIndexer nodes; SAMSON::getActiveDocument()->getNodes(nodes, SBNode::IsType(Type::Atom)); // put all the atoms in the nodeIndexer //3d Arrows example unsigned int nCylinders = 2 * nodes.size(); // we will need 2 cylinders by arrow, one for the head, one for the stick unsigned int nPositions = 4 * nodes.size(); // 3 position by arrow, the two end points and the middle unsigned int* indexData = new unsigned int[2 * nCylinders]; // this should be of size 2* cylinder, it will say for each end point at which position it should be float *positionData = new float[3 * nPositions]; // all the coordinates X Y Z of each positions, float *radiusData = new float[2 * nCylinders]; // the radius of the two end points of the cylinder can be different to make a cone unsigned int *capData = new unsigned int[2 * nCylinders]; // controls if the cylinders are closed or open float *colorData = new float[4 * 2 * nCylinders]; // the ARGB code for each end point of a cylinder unsigned int *flagData = new unsigned int[2 * nCylinders]; // controls if the cylinder is highlighted, selected int atomCounter = 0; SB_FOR(SBNode* n, nodes) { SBAtom* atom = (SBAtom*) n; SBVector3 arrowDirection(1, 0, 0); SBQuantity::length arrowLength(60); // give the position of the cone that is the head of the arrow positionData[atomCounter * 12 + 0] = (atom->getPosition().v[0] + arrowDirection.v[0] * SAMSON::getAtomRadius()).getValue(); positionData[atomCounter * 12 + 1] = (atom->getPosition().v[1] + arrowDirection.v[1] * SAMSON::getAtomRadius()).getValue(); positionData[atomCounter * 12 + 2] = (atom->getPosition().v[2] + arrowDirection.v[2] * SAMSON::getAtomRadius()).getValue(); positionData[atomCounter * 12 + 3] = (atom->getPosition().v[0] + arrowDirection.v[0] * (SAMSON::getAtomRadius() + 0.3 * arrowLength)).getValue(); positionData[atomCounter * 12 + 4] = (atom->getPosition().v[1] + arrowDirection.v[1] * (SAMSON::getAtomRadius() + 0.3 * arrowLength)).getValue(); positionData[atomCounter * 12 + 5] = (atom->getPosition().v[2] + arrowDirection.v[2] * (SAMSON::getAtomRadius() + 0.3 * arrowLength)).getValue(); // radii of the cone are 0 on the pointed size and 0 on the other side radiusData[atomCounter * 4 + 0] = 0; radiusData[atomCounter * 4 + 1] = 10; // give the position of the cylinder that is the tail of the arrow positionData[atomCounter * 12 + 6] = (atom->getPosition().v[0] + arrowDirection.v[0] * (SAMSON::getAtomRadius() + 0.3 * arrowLength)).getValue(); positionData[atomCounter * 12 + 7] = (atom->getPosition().v[1] + arrowDirection.v[1] * (SAMSON::getAtomRadius() + 0.3 * arrowLength)).getValue(); positionData[atomCounter * 12 + 8] = (atom->getPosition().v[2] + arrowDirection.v[2] * (SAMSON::getAtomRadius() + 0.3 * arrowLength)).getValue(); positionData[atomCounter * 12 + 9] = (atom->getPosition().v[0] + arrowDirection.v[0] * (SAMSON::getAtomRadius() + arrowLength)).getValue(); positionData[atomCounter * 12 + 10] = (atom->getPosition().v[1] + arrowDirection.v[1] * (SAMSON::getAtomRadius() + arrowLength)).getValue(); positionData[atomCounter * 12 + 11] = (atom->getPosition().v[2] + arrowDirection.v[2] * (SAMSON::getAtomRadius() + arrowLength)).getValue(); // radius of the tail is 2 everywhere radiusData[atomCounter * 4 + 2] = 2; radiusData[atomCounter * 4 + 3] = 2; indexData[atomCounter * 4 + 0] = 4 * atomCounter + 0; indexData[atomCounter * 4 + 1] = 4 * atomCounter + 1; indexData[atomCounter * 4 + 2] = 4 * atomCounter + 2; indexData[atomCounter * 4 + 3] = 4 * atomCounter + 3; capData[atomCounter * 4 + 0] = 1; capData[atomCounter * 4 + 1] = 1; capData[atomCounter * 4 + 2] = 1; capData[atomCounter * 4 + 3] = 1; colorData[atomCounter * 16 + 0 ] = 1; colorData[atomCounter * 16 + 1 ] = 1; colorData[atomCounter * 16 + 2 ] = 1; colorData[atomCounter * 16 + 3 ] = 1; colorData[atomCounter * 16 + 4 ] = 1; colorData[atomCounter * 16 + 5 ] = 1; colorData[atomCounter * 16 + 6 ] = 1; colorData[atomCounter * 16 + 7 ] = 1; colorData[atomCounter * 16 + 8 ] = 1; colorData[atomCounter * 16 + 9 ] = 1; colorData[atomCounter * 16 + 10] = 1; colorData[atomCounter * 16 + 11] = 1; colorData[atomCounter * 16 + 12] = 1; colorData[atomCounter * 16 + 13] = 1; colorData[atomCounter * 16 + 14] = 1; colorData[atomCounter * 16 + 15] = 1; unsigned int flag = (atom->isSelected() ? 1 : 0) + (atom->isHighlighted() ? 2 : 0); flagData[atomCounter * 4 + 0] = flag; flagData[atomCounter * 4 + 1] = flag; flagData[atomCounter * 4 + 2] = flag; flagData[atomCounter * 4 + 3] = flag; atomCounter++; } SAMSON::displayCylinders(nCylinders, nPositions, indexData, positionData, radiusData, capData, colorData, flagData); delete[] indexData; delete[] radiusData; delete[] capData; delete[] colorData; delete[] flagData; }
-
@guillaume Hi,
Thank you very much for this example. I will try it and send you a feedback. -
Hi @guillaume, I tried your example above and it works correctly. But now I would like to call the visual model by code (on click event of a button) instead of doing it from SAMSON "Visualization->Add visual model" menu. I tried like adding a structural model but it does not work. Can you help me, please?
Thank you.
-
@Guillaume, It's done :) Thanks
-
I'm glad you managed to do it, here is my solution if other people need it:
SEMyVisualModel* vm = new SEMyVisualModel();// create your visual model SAMSON::beginHolding("Create visual model"); // this is to have this action undoable SAMSON::hold(vm); // Give the property of the object to SAMSON, you will not have to delete it when it will be removed vm->create(); SAMSON::getActiveLayer()->addChild(vm); // add the visual model to a layer SAMSON::endHolding();
-
Hi @guillaume, please, I am facing a issue. Which paramters can I modify in order to get horizontal arrows or other directions arrows, please? Thank you in advance.
-
Hi @piriziwè ,
SBVector3 arrowDirection(1, 0, 0); SBQuantity::length arrowLength(60); // give the position of the cone that is the head of the arrow positionData[atomCounter * 12 + 0] = (atom->getPosition().v[0] + arrowDirection.v[0] * SAMSON::getAtomRadius()).getValue(); positionData[atomCounter * 12 + 1] = (atom->getPosition().v[1] + arrowDirection.v[1] * SAMSON::getAtomRadius()).getValue(); positionData[atomCounter * 12 + 2] = (atom->getPosition().v[2] + arrowDirection.v[2] * SAMSON::getAtomRadius()).getValue(); positionData[atomCounter * 12 + 3] = (atom->getPosition().v[0] + arrowDirection.v[0] * (SAMSON::getAtomRadius() + 0.3 * arrowLength)).getValue(); positionData[atomCounter * 12 + 4] = (atom->getPosition().v[1] + arrowDirection.v[1] * (SAMSON::getAtomRadius() + 0.3 * arrowLength)).getValue(); positionData[atomCounter * 12 + 5] = (atom->getPosition().v[2] + arrowDirection.v[2] * (SAMSON::getAtomRadius() + 0.3 * arrowLength)).getValue(); // radii of the cone are 0 on the pointed size and 0 on the other side radiusData[atomCounter * 4 + 0] = 0; radiusData[atomCounter * 4 + 1] = 10; // give the position of the cylinder that is the tail of the arrow positionData[atomCounter * 12 + 6] = (atom->getPosition().v[0] + arrowDirection.v[0] * (SAMSON::getAtomRadius() + 0.3 * arrowLength)).getValue(); positionData[atomCounter * 12 + 7] = (atom->getPosition().v[1] + arrowDirection.v[1] * (SAMSON::getAtomRadius() + 0.3 * arrowLength)).getValue(); positionData[atomCounter * 12 + 8] = (atom->getPosition().v[2] + arrowDirection.v[2] * (SAMSON::getAtomRadius() + 0.3 * arrowLength)).getValue(); positionData[atomCounter * 12 + 9] = (atom->getPosition().v[0] + arrowDirection.v[0] * (SAMSON::getAtomRadius() + arrowLength)).getValue(); positionData[atomCounter * 12 + 10] = (atom->getPosition().v[1] + arrowDirection.v[1] * (SAMSON::getAtomRadius() + arrowLength)).getValue(); positionData[atomCounter * 12 + 11] = (atom->getPosition().v[2] + arrowDirection.v[2] * (SAMSON::getAtomRadius() + arrowLength)).getValue(); // radius of the tail is 2 everywhere radiusData[atomCounter * 4 + 2] = 2; radiusData[atomCounter * 4 + 3] = 2;
I did not detailed this par much, you can change the value of arrow direction to get the direction you want for the arrow. It can even be a different value for different atoms., I will update the first post as well
-
Thank you @guillaume. I will try it and see. Have a nice weekend
-
Hi everybody, all my problems with arrows are solved. Thanks very much for your help.