Index: indra/newview/lltoolplacer.cpp
===================================================================
--- indra/newview/lltoolplacer.cpp	(révision 2220)
+++ indra/newview/lltoolplacer.cpp	(copie de travail)
@@ -36,10 +36,12 @@
 #include "lltoolplacer.h"
 
 // linden library headers
+#include "llsdutil.h"
 #include "llprimitive.h"
 
 // viewer headers
 #include "llbutton.h"
+#include "lldefaultperms.h"
 #include "llviewercontrol.h"
 #include "llfirstuse.h"
 #include "llfloatertools.h"
@@ -229,14 +231,6 @@
 							   gAgent.getID(), 1.0f, LLAudioEngine::AUDIO_TYPE_UI);
 	}
 
-	gMessageSystem->newMessageFast(_PREHASH_ObjectAdd);
-	gMessageSystem->nextBlockFast(_PREHASH_AgentData);
-	gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
-	gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-	gMessageSystem->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID());
-	gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
-	gMessageSystem->addU8Fast(_PREHASH_Material,	material);
-
 	U32 flags = 0;		// not selected
 	if (use_physics)
 	{
@@ -246,9 +240,9 @@
 	{
 		flags |= FLAGS_CREATE_SELECTED;
 	}
-	gMessageSystem->addU32Fast(_PREHASH_AddFlags, flags );
 
-	LLPCode volume_pcode;	// ...PCODE_VOLUME, or the original on error
+	LLVolumeParams *p_volume_params = &volume_params; // ...address of volume params, or 0 on error
+	LLPCode volume_pcode = LL_PCODE_VOLUME;	// ...PCODE_VOLUME, or the original on error
 	switch (pcode)
 	{
 	case LL_PCODE_SPHERE:
@@ -259,8 +253,6 @@
 		volume_params.setBeginAndEndT( 0.f, 1.f );
 		volume_params.setRatio	( 1, 1 );
 		volume_params.setShear	( 0, 0 );
-		LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem);
-		volume_pcode = LL_PCODE_VOLUME;
 		break;
 
 	case LL_PCODE_TORUS:
@@ -271,8 +263,6 @@
 		volume_params.setBeginAndEndT( 0.f, 1.f );
 		volume_params.setRatio	( 1.f, 0.25f );	// "top size"
 		volume_params.setShear	( 0, 0 );
-		LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem);
-		volume_pcode = LL_PCODE_VOLUME;
 		break;
 
 	case LLViewerObject::LL_VO_SQUARE_TORUS:
@@ -283,8 +273,6 @@
 		volume_params.setBeginAndEndT( 0.f, 1.f );
 		volume_params.setRatio	( 1.f, 0.25f );	// "top size"
 		volume_params.setShear	( 0, 0 );
-		LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem);
-		volume_pcode = LL_PCODE_VOLUME;
 		break;
 
 	case LLViewerObject::LL_VO_TRIANGLE_TORUS:
@@ -295,8 +283,6 @@
 		volume_params.setBeginAndEndT( 0.f, 1.f );
 		volume_params.setRatio	( 1.f, 0.25f );	// "top size"
 		volume_params.setShear	( 0, 0 );
-		LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem);
-		volume_pcode = LL_PCODE_VOLUME;
 		break;
 
 	case LL_PCODE_SPHERE_HEMI:
@@ -305,8 +291,6 @@
 		volume_params.setBeginAndEndT( 0.f, 0.5f );
 		volume_params.setRatio	( 1, 1 );
 		volume_params.setShear	( 0, 0 );
-		LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem);
-		volume_pcode = LL_PCODE_VOLUME;
 		break;
 
 	case LL_PCODE_CUBE:
@@ -315,8 +299,6 @@
 		volume_params.setBeginAndEndT( 0.f, 1.f );
 		volume_params.setRatio	( 1, 1 );
 		volume_params.setShear	( 0, 0 );
-		LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem);
-		volume_pcode = LL_PCODE_VOLUME;
 		break;
 
 	case LL_PCODE_PRISM:
@@ -325,8 +307,6 @@
 		volume_params.setBeginAndEndT( 0.f, 1.f );
 		volume_params.setRatio	( 0, 1 );
 		volume_params.setShear	( -0.5f, 0 );
-		LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem);
-		volume_pcode = LL_PCODE_VOLUME;
 		break;
 
 	case LL_PCODE_PYRAMID:
@@ -335,8 +315,6 @@
 		volume_params.setBeginAndEndT( 0.f, 1.f );
 		volume_params.setRatio	( 0, 0 );
 		volume_params.setShear	( 0, 0 );
-		LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem);
-		volume_pcode = LL_PCODE_VOLUME;
 		break;
 
 	case LL_PCODE_TETRAHEDRON:
@@ -345,8 +323,6 @@
 		volume_params.setBeginAndEndT( 0.f, 1.f );
 		volume_params.setRatio	( 0, 0 );
 		volume_params.setShear	( 0, 0 );
-		LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem);
-		volume_pcode = LL_PCODE_VOLUME;
 		break;
 
 	case LL_PCODE_CYLINDER:
@@ -355,8 +331,6 @@
 		volume_params.setBeginAndEndT( 0.f, 1.f );
 		volume_params.setRatio	( 1, 1 );
 		volume_params.setShear	( 0, 0 );
-		LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem);
-		volume_pcode = LL_PCODE_VOLUME;
 		break;
 
 	case LL_PCODE_CYLINDER_HEMI:
@@ -365,8 +339,6 @@
 		volume_params.setBeginAndEndT( 0.f, 1.f );
 		volume_params.setRatio	( 1, 1 );
 		volume_params.setShear	( 0, 0 );
-		LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem);
-		volume_pcode = LL_PCODE_VOLUME;
 		break;
 
 	case LL_PCODE_CONE:
@@ -375,8 +347,6 @@
 		volume_params.setBeginAndEndT( 0.f, 1.f );
 		volume_params.setRatio	( 0, 0 );
 		volume_params.setShear	( 0, 0 );
-		LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem);
-		volume_pcode = LL_PCODE_VOLUME;
 		break;
 
 	case LL_PCODE_CONE_HEMI:
@@ -385,25 +355,13 @@
 		volume_params.setBeginAndEndT( 0.f, 1.f );
 		volume_params.setRatio	( 0, 0 );
 		volume_params.setShear	( 0, 0 );
-		LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem);
-		volume_pcode = LL_PCODE_VOLUME;
 		break;
 
 	default:
-		LLVolumeMessage::packVolumeParams(0, gMessageSystem);
+		p_volume_params = 0;
 		volume_pcode = pcode;
-		break;
 	}
-	gMessageSystem->addU8Fast(_PREHASH_PCode, volume_pcode);
 
-	gMessageSystem->addVector3Fast(_PREHASH_Scale,			scale );
-	gMessageSystem->addQuatFast(_PREHASH_Rotation,			rotation );
-	gMessageSystem->addVector3Fast(_PREHASH_RayStart,		ray_start_region );
-	gMessageSystem->addVector3Fast(_PREHASH_RayEnd,			ray_end_region );
-	gMessageSystem->addU8Fast(_PREHASH_BypassRaycast,		(U8)b_hit_land );
-	gMessageSystem->addU8Fast(_PREHASH_RayEndIsIntersection, (U8)FALSE );
-	gMessageSystem->addU8Fast(_PREHASH_State, state);
-
 	// Limit raycast to a single object.  
 	// Speeds up server raycast + avoid problems with server ray hitting objects
 	// that were clipped by the near plane or culled on the viewer.
@@ -416,11 +374,76 @@
 	{
 		ray_target_id.setNull();
 	}
-	gMessageSystem->addUUIDFast(_PREHASH_RayTargetID,			ray_target_id );
-	
-	// Pack in name value pairs
-	gMessageSystem->sendReliable(regionp->getHost());
 
+	std::string url;
+	url = regionp->getCapability("ObjectAdd");
+
+	if (!url.empty())
+	{
+		LLSD body;
+llinfos << "new capabilities system" << llendl;
+
+		// Agent data
+		body["AgentData"]["AgentId"]		= gAgent.getID();
+		body["AgentData"]["SessionId"]		= gAgent.getSessionID();
+		body["AgentData"]["GroupId"]		= gAgent.getGroupID();
+
+		// Object data
+		body["ObjectData"]["Material"]		= material;
+		body["ObjectData"]["Flags"]		= ll_sd_from_U32(flags);
+		LLVolumeMessage::packVolumeParams(
+			p_volume_params, body["ObjectData"]);
+		body["ObjectData"]["PCode"]		= volume_pcode;
+		body["ObjectData"]["Scale"]		= ll_sd_from_vector3(scale);
+		body["ObjectData"]["Rotation"]		= ll_sd_from_quaternion(rotation);
+		body["ObjectData"]["RayStart"]		= ll_sd_from_vector3(ray_start_region);
+		body["ObjectData"]["RayEnd"]		= ll_sd_from_vector3(ray_end_region);
+		body["ObjectData"]["BypassRaycast"]	= (bool)b_hit_land;
+		body["ObjectData"]["RayEndIsIntersection"] = (bool)FALSE;
+		body["ObjectData"]["State"]		= state;
+		body["ObjectData"]["RayTargetId"]	= ray_target_id;
+
+		// New permission fields
+		U32 group_mask = LLDefaultPerms::getGroupPerms(),
+			everyone_mask = LLDefaultPerms::getEveryonePerms(),
+			next_owner_mask = LLDefaultPerms::getNextOwnerPerms();
+		body["ObjectData"]["GroupMask"]		= ll_sd_from_U32(group_mask);
+		body["ObjectData"]["EveryoneMask"]	= ll_sd_from_U32(everyone_mask);
+		body["ObjectData"]["NextOwnerMask"]	= ll_sd_from_U32(next_owner_mask);
+
+		LLHTTPClient::post(url, body, new LLHTTPClient::Responder());
+// new objectAddResponder(body) ??? (Catherine Pfeffer)
+	}
+	else
+	{
+		LLMessageSystem* msg = gMessageSystem;
+llinfos << "old message system" << llendl;
+
+		msg->newMessageFast(_PREHASH_ObjectAdd);
+
+		msg->nextBlockFast(_PREHASH_AgentData);
+		msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+		msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+		msg->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID());
+
+		msg->nextBlockFast(_PREHASH_ObjectData);
+		msg->addU8Fast(_PREHASH_Material, material);
+		msg->addU32Fast(_PREHASH_AddFlags, flags );
+		LLVolumeMessage::packVolumeParams(p_volume_params, gMessageSystem);
+		msg->addU8Fast(_PREHASH_PCode, volume_pcode);
+		msg->addVector3Fast(_PREHASH_Scale,	scale );
+		msg->addQuatFast(_PREHASH_Rotation,	rotation );
+		msg->addVector3Fast(_PREHASH_RayStart, ray_start_region );
+		msg->addVector3Fast(_PREHASH_RayEnd, ray_end_region );
+		msg->addU8Fast(_PREHASH_BypassRaycast, (U8)b_hit_land );
+		msg->addU8Fast(_PREHASH_RayEndIsIntersection, (U8)FALSE );
+		msg->addU8Fast(_PREHASH_State, state);
+		msg->addUUIDFast(_PREHASH_RayTargetID, ray_target_id );
+
+		gMessageSystem->sendReliable(regionp->getHost());
+	}
+llinfos << "message sent" << llendl;
+
 	// Spawns a message, so must be after above send
 	if (create_selected)
 	{
Index: indra/llprimitive/llvolumemessage.h
===================================================================
--- indra/llprimitive/llvolumemessage.h	(révision 2220)
+++ indra/llprimitive/llvolumemessage.h	(copie de travail)
@@ -52,6 +52,9 @@
 	static bool packProfileParams(
 		const LLProfileParams* params,
 		LLDataPacker& dp);
+	static bool packProfileParams(
+		const LLProfileParams* params,
+		LLSD &data);
 	static bool unpackProfileParams(
 		LLProfileParams* params,
 		LLMessageSystem* mesgsys,
@@ -62,7 +65,12 @@
 	static bool packPathParams(
 		const LLPathParams* params,
 		LLMessageSystem* mesgsys);
-	static bool packPathParams(const LLPathParams* params, LLDataPacker& dp);
+	static bool packPathParams(
+		const LLPathParams* params,
+		LLDataPacker& dp);
+	static bool packPathParams(
+		const LLPathParams* params,
+		LLSD &data);
 	static bool unpackPathParams(
 		LLPathParams* params,
 		LLMessageSystem* mesgsys,
@@ -86,6 +94,9 @@
 	static bool packVolumeParams(
 		const LLVolumeParams* params,
 		LLDataPacker& dp);
+	static bool packVolumeParams(
+		const LLVolumeParams* params,
+		LLSD& data);
 	static bool unpackVolumeParams(
 		LLVolumeParams* params,
 		LLMessageSystem* mesgsys,
Index: indra/llprimitive/llvolumemessage.cpp
===================================================================
--- indra/llprimitive/llvolumemessage.cpp	(révision 2220)
+++ indra/llprimitive/llvolumemessage.cpp	(copie de travail)
@@ -97,6 +97,36 @@
 	return true;
 }
 
+// IMPORTANT NOTE: is it still worth "packing" that much the data with LLSD?
+// Wouldn't it be simpler to send the data "as is" ? -- Catherine Pfeffer
+bool LLVolumeMessage::packProfileParams(
+	const LLProfileParams* params,
+	LLSD &data)
+{
+	// Default to cylinder
+	static LLProfileParams defaultparams(LL_PCODE_PROFILE_CIRCLE, U16(0), U16(0), U16(0));
+
+	if (!params)
+		params = &defaultparams;
+
+	U8 tempU8;
+	U16 tempU16;
+
+	tempU8 = params->getCurveType();
+	data["Profile"]["Curve"] = tempU8;
+
+	tempU16 = (U16) llround( params->getBegin() / CUT_QUANTA);
+	data["Profile"]["Begin"] = tempU16;
+
+	tempU16 = 50000 - (U16) llround(params->getEnd() / CUT_QUANTA);
+	data["Profile"]["End"] = tempU16;
+
+	tempU16 = (U16) llround(params->getHollow() / HOLLOW_QUANTA);
+	data["Profile"]["Hollow"] = tempU16;
+
+	return true;
+}
+
 bool LLVolumeMessage::unpackProfileParams(
 	LLProfileParams* params,
 	LLMessageSystem* mesgsys,
@@ -325,6 +355,65 @@
 	return true;
 }
 
+// IMPORTANT NOTE: is it still worth "packing" that much the data with LLSD?
+// Wouldn't it be simpler to send the data "as is" ? -- Catherine Pfeffer
+bool LLVolumeMessage::packPathParams(
+	const LLPathParams* params,
+	LLSD &data)
+{
+	// Default to cylinder with no cut, top same size as bottom, no shear, no twist
+	static LLPathParams defaultparams(LL_PCODE_PATH_LINE, U8(0), U8(0), U8(0), U8(0), U8(0), U8(0), U8(0), U8(0), U8(0), U8(0), U8(0), U8(0), 0);
+	if (!params)
+		params = &defaultparams;
+	
+	U8 curve = params->getCurveType();
+	data["Path"]["Curve"] = curve;
+
+	U16 begin = (U16) llround(params->getBegin() / CUT_QUANTA);
+	data["Path"]["Begin"] = begin;
+
+	U16 end = 50000 - (U16) llround(params->getEnd() / CUT_QUANTA);
+	data["Path"]["End"] = end;
+
+	// Avoid truncation problem with direct F32->U8 cast.
+	// (e.g., (U8) (0.50 / 0.01) = (U8) 49.9999999 = 49 not 50.
+
+	U8 pack_scale_x = 200 - (U8) llround(params->getScaleX() / SCALE_QUANTA);
+	data["Path"]["ScaleX"] = pack_scale_x;
+
+	U8 pack_scale_y = 200 - (U8) llround(params->getScaleY() / SCALE_QUANTA);
+	data["Path"]["ScaleY"] = pack_scale_y;
+
+	S8 pack_shear_x = (S8) llround(params->getShearX() / SHEAR_QUANTA);
+	data["Path"]["ShearX"] = *(U8 *)&pack_shear_x;
+
+	S8 pack_shear_y = (S8) llround(params->getShearY() / SHEAR_QUANTA);
+	data["Path"]["ShearY"] = *(U8 *)&pack_shear_y;
+
+	S8 twist = (S8) llround(params->getTwist() / SCALE_QUANTA);
+	data["Path"]["Twist"] = *(U8 *)&twist;
+
+	S8 twist_begin = (S8) llround(params->getTwistBegin() / SCALE_QUANTA);
+	data["Path"]["TwistBegin"] = *(U8 *)&twist_begin;
+
+	S8 radius_offset = (S8) llround(params->getRadiusOffset() / SCALE_QUANTA);
+	data["Path"]["RadiusOffset"] = *(U8 *)&radius_offset;
+
+	S8 taper_x = (S8) llround(params->getTaperX() / TAPER_QUANTA);
+	data["Path"]["TaperX"] = *(U8 *)&taper_x;
+
+	S8 taper_y = (S8) llround(params->getTaperY() / TAPER_QUANTA);
+	data["Path"]["TaperY"] = *(U8 *)&taper_y;
+
+	U8 revolutions = (U8) llround( (params->getRevolutions() - 1.0f) / REV_QUANTA);
+	data["Path"]["Revolutions"] = *(U8 *)&revolutions;
+
+	S8 skew = (S8) llround(params->getSkew() / SCALE_QUANTA);
+	data["Path"]["Skew"] = *(U8 *)&skew;
+
+	return true;
+}
+
 bool LLVolumeMessage::unpackPathParams(
 	LLPathParams* params,
 	LLMessageSystem* mesgsys,
@@ -525,6 +614,22 @@
 	return true;
 }
 
+bool LLVolumeMessage::packVolumeParams(const LLVolumeParams* params, LLSD &data)
+{
+	// llinfos << "pack volume" << llendl;
+	if (params)
+	{
+		packPathParams(&params->getPathParams(), data);
+		packProfileParams(&params->getProfileParams(), data);
+	}
+	else
+	{
+		packPathParams(0, data);
+		packProfileParams(0, data);
+	}
+	return true;
+}
+
 bool LLVolumeMessage::unpackVolumeParams(
 	LLVolumeParams* params,
 	LLMessageSystem* mesgsys,
