Drawing arrows on atoms



  • Hi,
    I would like to draw arrows on atoms in order to indicate the user how to apply forces on atoms. Is it possible to do in SAMSON? If yes, would anyone mind helping me do it, please? Here is what I would like to get as result in SAMSON if possible:
    0_1513091967167_result.png
    Thank you in advance.



  • @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;
    		
    }
    

    0_1513098165495_Untitled.png



  • @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.


Log in to reply
 















Web
Analytics

Looks like your connection to SAMSON Connect - Forum was lost, please wait while we try to reconnect.