<commit_before>//-----------------------------------------------------------------------------
// Copyright (c) 2015 Michael G. Brehm
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//-----------------------------------------------------------------------------

#include "stdafx.h"
#include "VirtualMachine.h"

#include "Exception.h"
#include "LinuxException.h"
#include "MountOptions.h"
#include "Namespace.h"
#include "RpcObject.h"
#include "Session.h"
#include "Win32Exception.h"

// System Call RPC Interfaces
//
#include <syscalls32.h>
#ifdef _M_X64
#include <syscalls64.h>
#endif

// File Systems
//
#include "HostFileSystem.h"
#include "RootFileSystem.h"
//#include "TempFileSystem.h"

#pragma warning(push, 4)

// VirtualMachine::s_instances
//
// Static collection of active virtual machine instances
VirtualMachine::instance_map_t VirtualMachine::s_instances;

// VirtualMachine::s_lock
//
// Synchronization object for active virtual machine collection
VirtualMachine::instance_map_lock_t VirtualMachine::s_instancelock;

//-----------------------------------------------------------------------------
// AddVirtualMachineSession
//
// Adds a session into a virtual machine
//
// Arguments:
//
//	vm			- VirtualMachine instance to operate against
//	session		- Session instance to be added

std::shared_ptr<VirtualMachine> AddVirtualMachineSession(std::shared_ptr<VirtualMachine> vm, std::shared_ptr<Session> session)
{
	sync::critical_section::scoped_lock cs{ vm->m_sessionslock };
	if(!vm->m_sessions.emplace(session.get(), session).second) throw LinuxException{ LINUX_ENOMEM };

	return vm;
}

//-----------------------------------------------------------------------------
// RemoveVirtualMachineSession
//
// Removes a session from a VirtualMachine instance
//
// Arguments:
//
//	vm			- VirtualMachine instance to operate against
//	session		- Session instance to be removed

void RemoveVirtualMachineSession(std::shared_ptr<VirtualMachine> vm, const Session* session)
{
	sync::critical_section::scoped_lock cs{ vm->m_sessionslock };
	vm->m_sessions.erase(session);
}

//---------------------------------------------------------------------------
// VirtualMachine Constructor
//
// Arguments:
//
//	NONE

VirtualMachine::VirtualMachine() : m_instanceid(GenerateInstanceId())
{
}

//---------------------------------------------------------------------------
// VirtualMachine::Find (static)
//
// Locates an active virtual machine instance based on its uuid
//
// Arguments:
//
//	instanceid	- Virtual machine instance identifier

std::shared_ptr<VirtualMachine> VirtualMachine::Find(const uuid_t& instanceid)
{
	instance_map_lock_t::scoped_lock_read reader(s_instancelock);

	// Attempt to locate the instanceid in the collection
	auto iterator = s_instances.find(instanceid);
	return (iterator != s_instances.end()) ? iterator->second : nullptr;
}

//---------------------------------------------------------------------------
// VirtualMachine::GenerateInstanceId (static, private)
//
// Generate the universally unique identifier for this virtual machine instance
//
// Arguments:
//
//	NONE

uuid_t VirtualMachine::GenerateInstanceId(void)
{
	uuid_t			instanceid;			// Generated instance identifier

	// Attempt to generate a new uuid_t for this virtual machine instance
	RPC_STATUS rpcresult = UuidCreate(&instanceid);
	if(rpcresult != RPC_S_OK) throw Win32Exception(rpcresult);

	return instanceid;
}

//---------------------------------------------------------------------------
// VirtualMachine::OnStart (private)
//
// Invoked when the service is started
//
// Arguments:
//
//	argc		- Number of command line arguments
//	argv		- Array of command line argument strings

void VirtualMachine::OnStart(int argc, LPTSTR* argv)
{
	// The command line arguments should be used to override defaults
	// set in the service parameters.  This functionality should be
	// provided by servicelib directly -- look into that (todo)
	UNREFERENCED_PARAMETER(argc);
	UNREFERENCED_PARAMETER(argv);

	try {

		// ROOT NAMESPACE
		//
		m_rootns = Namespace::Create();

		// PROPERTIES
		//

		// SYSTEM LOG
		//

		// FILE SYSTEMS
		//
		m_filesystems.emplace("hostfs",	HostFileSystem::Mount);
		//m_filesystems.emplace("procfs", ProcFileSystem::Mount);
		m_filesystems.emplace("rootfs",	RootFileSystem::Mount);
		//m_filesystems.emplace("sysfs", SysFileSystem::Mount);
		//m_filesystems.emplace("tmpfs", TempFileSystem::Mount);

		// ROOT FILE SYSTEM
		//
		auto root = std::to_string(m_paramroot.Value);
		auto rootfstype = std::to_string(m_paramrootfstype.Value);
		auto rootflags = std::to_string(m_paramrootflags.Value);

		// todo: ro, rw, etc. -- these are kernel parameters

		// Attempt to mount the root file system using the provided parameters
		try { m_rootmount = m_filesystems.at(rootfstype.c_str())(root.c_str(), LINUX_MS_KERNMOUNT, rootflags.data(), rootflags.length()); }
		catch(...) { throw; } // <--- todo - service should not start if root mount fails - panic

		// Construct the file system root alias (/)
		m_rootalias = std::make_shared<RootAlias>(m_rootmount->Root);

		// add mount to root namespace
		//m_rootmount = RootFileSystem::Mount(

		// INITRAMFS
		//
		auto initrd = std::to_string(m_paraminitrd.Value);
		// extract ramdisk here if there is one

		// INIT PROCESS
		//
		auto init = std::to_string(m_paraminit.Value);
		// note: init is the only process that is ever directly spawned, everything
		// else that comes after this will be fork-exec

		// Allocate the init process pid
		auto initpid = m_rootns->Pids->Allocate();
		_ASSERTE(initpid->getValue(m_rootns) == 1);

		// SYSTEM CALL RPC OBJECTS
		//
		m_syscalls32 = RpcObject::Create(SystemCalls32_v1_0_s_ifspec, m_instanceid, RPC_IF_AUTOLISTEN | RPC_IF_ALLOW_SECURE_ONLY);
#ifdef _M_X64
		m_syscalls64 = RpcObject::Create(SystemCalls64_v1_0_s_ifspec, m_instanceid, RPC_IF_AUTOLISTEN | RPC_IF_ALLOW_SECURE_ONLY);
#endif

		// NOTE: DON'T START INIT PROCESS UNTIL AFTER THE RPC OBJECTS HAVE BEEN CONSTRUCTED
	}

	// Win32Exception and Exception can be translated into ServiceExceptions
	catch(Win32Exception& ex) { throw ServiceException(static_cast<DWORD>(ex.Code)); }
	catch(Exception& ex) { throw ServiceException(ex.HResult); }
	// catch(std::exception& ex) { /* TODO: PUT SOMETHING HERE */ }

	// Add this virtual machine instance to the active instance collection
	instance_map_lock_t::scoped_lock_write writer(s_instancelock);
	s_instances.emplace(m_instanceid, shared_from_this());
}

//---------------------------------------------------------------------------
// VirtualMachine::OnStop (private)
//
// Invoked when the service is stopped
//
// Arguments:
//
//	NONE

void VirtualMachine::OnStop(void)
{
	m_syscalls32.reset();			// Revoke the 32-bit system calls object
#ifdef _M_X64
	m_syscalls64.reset();			// Revoke the 64-bit system calls object
#endif

	// Remove this virtual machine from the active instance collection
	instance_map_lock_t::scoped_lock_write writer(s_instancelock);
	s_instances.erase(m_instanceid);
}

//
// VIRTUALMACHINE::ROOTALIAS
//

//-----------------------------------------------------------------------------
// VirtualMachine::RootAlias Constructor
//
// Arguments:
//
//	dir			- Directory node to attach to this alias

VirtualMachine::RootAlias::RootAlias(std::shared_ptr<FileSystem::Directory> dir) : m_dir(std::move(dir))
{
}

//-----------------------------------------------------------------------------
// VirtualMachine::RootAlias::GetName
//
// Reads the name assigned to this alias
//
// Arguments:
//
//	buffer			- Output buffer
//	count			- Size of the output buffer, in bytes

uapi::size_t VirtualMachine::RootAlias::GetName(char_t* buffer, size_t count) const
{
	UNREFERENCED_PARAMETER(count);

	if(buffer == nullptr) throw LinuxException(LINUX_EFAULT);
	return 0;
}

//-----------------------------------------------------------------------------
// VirtualMachine::RootAlias::getName
//
// Gets the name assigned to this alias

std::string VirtualMachine::RootAlias::getName(void) const
{
	return std::string();
}

//-----------------------------------------------------------------------------
// VirtualMachine::RootAlias::getNode
//
// Gets the node to which this alias refers

std::shared_ptr<FileSystem::Node> VirtualMachine::RootAlias::getNode(void) const
{
	return m_dir;
}

//---------------------------------------------------------------------------

#pragma warning(pop)
<commit_msg>Set up the RPC listeners before setting up the init process during service start<commit_after>//-----------------------------------------------------------------------------
// Copyright (c) 2015 Michael G. Brehm
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//-----------------------------------------------------------------------------

#include "stdafx.h"
#include "VirtualMachine.h"

#include "Exception.h"
#include "LinuxException.h"
#include "MountOptions.h"
#include "Namespace.h"
#include "ProcessGroup.h"
#include "RpcObject.h"
#include "Session.h"
#include "Win32Exception.h"

// System Call RPC Interfaces
//
#include <syscalls32.h>
#ifdef _M_X64
#include <syscalls64.h>
#endif

// File Systems
//
#include "HostFileSystem.h"
#include "RootFileSystem.h"
//#include "TempFileSystem.h"

#pragma warning(push, 4)

// VirtualMachine::s_instances
//
// Static collection of active virtual machine instances
VirtualMachine::instance_map_t VirtualMachine::s_instances;

// VirtualMachine::s_lock
//
// Synchronization object for active virtual machine collection
VirtualMachine::instance_map_lock_t VirtualMachine::s_instancelock;

//-----------------------------------------------------------------------------
// AddVirtualMachineSession
//
// Adds a session into a virtual machine
//
// Arguments:
//
//	vm			- VirtualMachine instance to operate against
//	session		- Session instance to be added

std::shared_ptr<VirtualMachine> AddVirtualMachineSession(std::shared_ptr<VirtualMachine> vm, std::shared_ptr<Session> session)
{
	sync::critical_section::scoped_lock cs{ vm->m_sessionslock };
	if(!vm->m_sessions.emplace(session.get(), session).second) throw LinuxException{ LINUX_ENOMEM };

	return vm;
}

//-----------------------------------------------------------------------------
// RemoveVirtualMachineSession
//
// Removes a session from a VirtualMachine instance
//
// Arguments:
//
//	vm			- VirtualMachine instance to operate against
//	session		- Session instance to be removed

void RemoveVirtualMachineSession(std::shared_ptr<VirtualMachine> vm, const Session* session)
{
	sync::critical_section::scoped_lock cs{ vm->m_sessionslock };
	vm->m_sessions.erase(session);
}

//---------------------------------------------------------------------------
// VirtualMachine Constructor
//
// Arguments:
//
//	NONE

VirtualMachine::VirtualMachine() : m_instanceid(GenerateInstanceId())
{
}

//---------------------------------------------------------------------------
// VirtualMachine::Find (static)
//
// Locates an active virtual machine instance based on its uuid
//
// Arguments:
//
//	instanceid	- Virtual machine instance identifier

std::shared_ptr<VirtualMachine> VirtualMachine::Find(const uuid_t& instanceid)
{
	instance_map_lock_t::scoped_lock_read reader(s_instancelock);

	// Attempt to locate the instanceid in the collection
	auto iterator = s_instances.find(instanceid);
	return (iterator != s_instances.end()) ? iterator->second : nullptr;
}

//---------------------------------------------------------------------------
// VirtualMachine::GenerateInstanceId (static, private)
//
// Generate the universally unique identifier for this virtual machine instance
//
// Arguments:
//
//	NONE

uuid_t VirtualMachine::GenerateInstanceId(void)
{
	uuid_t			instanceid;			// Generated instance identifier

	// Attempt to generate a new uuid_t for this virtual machine instance
	RPC_STATUS rpcresult = UuidCreate(&instanceid);
	if(rpcresult != RPC_S_OK) throw Win32Exception(rpcresult);

	return instanceid;
}

//---------------------------------------------------------------------------
// VirtualMachine::OnStart (private)
//
// Invoked when the service is started
//
// Arguments:
//
//	argc		- Number of command line arguments
//	argv		- Array of command line argument strings

void VirtualMachine::OnStart(int argc, LPTSTR* argv)
{
	// The command line arguments should be used to override defaults
	// set in the service parameters.  This functionality should be
	// provided by servicelib directly -- look into that (todo)
	UNREFERENCED_PARAMETER(argc);
	UNREFERENCED_PARAMETER(argv);

	try {

		// ROOT NAMESPACE
		//
		m_rootns = Namespace::Create();

		// PROPERTIES
		//

		// SYSTEM LOG
		//

		// FILE SYSTEMS
		//
		m_filesystems.emplace("hostfs",	HostFileSystem::Mount);
		//m_filesystems.emplace("procfs", ProcFileSystem::Mount);
		m_filesystems.emplace("rootfs",	RootFileSystem::Mount);
		//m_filesystems.emplace("sysfs", SysFileSystem::Mount);
		//m_filesystems.emplace("tmpfs", TempFileSystem::Mount);

		// ROOT FILE SYSTEM
		//
		auto root = std::to_string(m_paramroot.Value);
		auto rootfstype = std::to_string(m_paramrootfstype.Value);
		auto rootflags = std::to_string(m_paramrootflags.Value);

		// todo: ro, rw, etc. -- these are kernel parameters

		// Attempt to mount the root file system using the provided parameters
		try { m_rootmount = m_filesystems.at(rootfstype.c_str())(root.c_str(), LINUX_MS_KERNMOUNT, rootflags.data(), rootflags.length()); }
		catch(...) { throw; } // <--- todo - service should not start if root mount fails - panic

		// Construct the file system root alias (/)
		m_rootalias = std::make_shared<RootAlias>(m_rootmount->Root);

		// add mount to root namespace
		//m_rootmount = RootFileSystem::Mount(

		// INITRAMFS
		//
		auto initrd = std::to_string(m_paraminitrd.Value);
		// extract ramdisk here if there is one

		// SYSTEM CALL LISTENERS
		//
		m_syscalls32 = RpcObject::Create(SystemCalls32_v1_0_s_ifspec, m_instanceid, RPC_IF_AUTOLISTEN | RPC_IF_ALLOW_SECURE_ONLY);
#ifdef _M_X64
		m_syscalls64 = RpcObject::Create(SystemCalls64_v1_0_s_ifspec, m_instanceid, RPC_IF_AUTOLISTEN | RPC_IF_ALLOW_SECURE_ONLY);
#endif

		// INIT PROCESS
		//
		auto initpath = std::to_string(m_paraminit.Value);
		// initpath must exist

		auto initpid = m_rootns->Pids->Allocate();
		_ASSERTE(initpid->getValue(m_rootns) == 1);

		auto initsession = Session::Create(initpid, shared_from_this());
		auto initpgroup = ProcessGroup::Create(initpid, initsession);

		// initprocess must be watched, termination causes a panic (service stop)
	}

	// Win32Exception and Exception can be translated into ServiceExceptions
	catch(Win32Exception& ex) { throw ServiceException(static_cast<DWORD>(ex.Code)); }
	catch(Exception& ex) { throw ServiceException(ex.HResult); }
	// catch(std::exception& ex) { /* TODO: PUT SOMETHING HERE */ }

	// Add this virtual machine instance to the active instance collection
	instance_map_lock_t::scoped_lock_write writer(s_instancelock);
	s_instances.emplace(m_instanceid, shared_from_this());
}

//---------------------------------------------------------------------------
// VirtualMachine::OnStop (private)
//
// Invoked when the service is stopped
//
// Arguments:
//
//	NONE

void VirtualMachine::OnStop(void)
{
	m_syscalls32.reset();			// Revoke the 32-bit system calls object
#ifdef _M_X64
	m_syscalls64.reset();			// Revoke the 64-bit system calls object
#endif

	// Remove this virtual machine from the active instance collection
	instance_map_lock_t::scoped_lock_write writer(s_instancelock);
	s_instances.erase(m_instanceid);
}

//
// VIRTUALMACHINE::ROOTALIAS
//

//-----------------------------------------------------------------------------
// VirtualMachine::RootAlias Constructor
//
// Arguments:
//
//	dir			- Directory node to attach to this alias

VirtualMachine::RootAlias::RootAlias(std::shared_ptr<FileSystem::Directory> dir) : m_dir(std::move(dir))
{
}

//-----------------------------------------------------------------------------
// VirtualMachine::RootAlias::GetName
//
// Reads the name assigned to this alias
//
// Arguments:
//
//	buffer			- Output buffer
//	count			- Size of the output buffer, in bytes

uapi::size_t VirtualMachine::RootAlias::GetName(char_t* buffer, size_t count) const
{
	UNREFERENCED_PARAMETER(count);

	if(buffer == nullptr) throw LinuxException(LINUX_EFAULT);
	return 0;
}

//-----------------------------------------------------------------------------
// VirtualMachine::RootAlias::getName
//
// Gets the name assigned to this alias

std::string VirtualMachine::RootAlias::getName(void) const
{
	return std::string();
}

//-----------------------------------------------------------------------------
// VirtualMachine::RootAlias::getNode
//
// Gets the node to which this alias refers

std::shared_ptr<FileSystem::Node> VirtualMachine::RootAlias::getNode(void) const
{
	return m_dir;
}

//---------------------------------------------------------------------------

#pragma warning(pop)
<|endoftext|>


<commit_before>#include "TPad.h"
#include "TPoint.h"
#include "TPadPainter.h"
#include "TVirtualX.h"
#include "TImage.h"

// Local scratch buffer for screen points, faster than allocating buffer on heap
const Int_t kPXY = 1002;
static TPoint gPXY[kPXY];

ClassImp(TPadPainter)

//______________________________________________________________________________
TPadPainter::TPadPainter()
{
   //Empty ctor. Here only because of explicit copy ctor.
}

/*
Line/fill/etc. attributes can be set inside TPad, but not only where:
many of them are set by base sub-objects of 2d primitives
(2d primitives usually inherit TAttLine or TAttFill etc.).  And these sub-objects
call gVirtualX->SetLineWidth ... etc. So, if I save some attributes in my painter,
it will be mess - at any moment I do not know, where to take line attribute - from
gVirtualX or from my own member. So! All attributed, _ALL_ go to/from gVirtualX.
*/

//______________________________________________________________________________
Color_t TPadPainter::GetLineColor() const
{
   // Delegate to gVirtualX.

   return gVirtualX->GetLineColor();
}

//______________________________________________________________________________
Style_t TPadPainter::GetLineStyle() const
{
   // Delegate to gVirtualX.

   return gVirtualX->GetLineStyle();
}

//______________________________________________________________________________
Width_t TPadPainter::GetLineWidth() const
{
   // Delegate to gVirtualX.

   return gVirtualX->GetLineWidth();
}

//______________________________________________________________________________
void TPadPainter::SetLineColor(Color_t lcolor)
{
   // Delegate to gVirtualX.

   gVirtualX->SetLineColor(lcolor);
}

//______________________________________________________________________________
void TPadPainter::SetLineStyle(Style_t lstyle)
{
   // Delegate to gVirtualX.

   gVirtualX->SetLineStyle(lstyle);
}

//______________________________________________________________________________
void TPadPainter::SetLineWidth(Width_t lwidth)
{
   // Delegate to gVirtualX.

   gVirtualX->SetLineWidth(lwidth);
}

//______________________________________________________________________________
Color_t TPadPainter::GetFillColor() const
{
   // Delegate to gVirtualX.

   return gVirtualX->GetFillColor();
}

//______________________________________________________________________________
Style_t TPadPainter::GetFillStyle() const
{
   // Delegate to gVirtualX.

   return gVirtualX->GetFillStyle();
}

//______________________________________________________________________________
Bool_t TPadPainter::IsTransparent() const
{
   // Delegate to gVirtualX.

   //IsTransparent is implemented as inline function in TAttFill.
   return gVirtualX->IsTransparent();
}

//______________________________________________________________________________
void TPadPainter::SetFillColor(Color_t fcolor)
{
   // Delegate to gVirtualX.

   gVirtualX->SetFillColor(fcolor);
}

//______________________________________________________________________________
void TPadPainter::SetFillStyle(Style_t fstyle)
{
   // Delegate to gVirtualX.

   gVirtualX->SetFillStyle(fstyle);
}

//______________________________________________________________________________
void TPadPainter::SetOpacity(Int_t percent)
{
   // Delegate to gVirtualX.

   gVirtualX->SetOpacity(percent);
}

//______________________________________________________________________________
Short_t TPadPainter::GetTextAlign() const
{
   // Delegate to gVirtualX.

   return gVirtualX->GetTextAlign();
}

//______________________________________________________________________________
Float_t TPadPainter::GetTextAngle() const
{
   // Delegate to gVirtualX.

   return gVirtualX->GetTextAngle();
}

//______________________________________________________________________________
Color_t TPadPainter::GetTextColor() const
{
   // Delegate to gVirtualX.

   return gVirtualX->GetTextColor();
}

//______________________________________________________________________________
Font_t TPadPainter::GetTextFont() const
{
   // Delegate to gVirtualX.

   return gVirtualX->GetTextFont();
}

//______________________________________________________________________________
Float_t TPadPainter::GetTextSize() const
{
   // Delegate to gVirtualX.

   return gVirtualX->GetTextSize();
}

//______________________________________________________________________________
Float_t TPadPainter::GetTextMagnitude() const
{
   // Delegate to gVirtualX.

   return gVirtualX->GetTextMagnitude();
}

//______________________________________________________________________________
void TPadPainter::SetTextAlign(Short_t align)
{
   // Delegate to gVirtualX.

   gVirtualX->SetTextAlign(align);
}

//______________________________________________________________________________
void TPadPainter::SetTextAngle(Float_t tangle)
{
   // Delegate to gVirtualX.

   gVirtualX->SetTextAngle(tangle);
}

//______________________________________________________________________________
void TPadPainter::SetTextColor(Color_t tcolor)
{
   // Delegate to gVirtualX.

   gVirtualX->SetTextColor(tcolor);
}

//______________________________________________________________________________
void TPadPainter::SetTextFont(Font_t tfont)
{
   // Delegate to gVirtualX.

   gVirtualX->SetTextFont(tfont);
}

//______________________________________________________________________________
void TPadPainter::SetTextSize(Float_t tsize)
{
   // Delegate to gVirtualX.

   gVirtualX->SetTextSize(tsize);
}

//______________________________________________________________________________
void TPadPainter::SetTextSizePixels(Int_t npixels)
{
   // Delegate to gVirtualX.

   gVirtualX->SetTextSizePixels(npixels);
}

//______________________________________________________________________________
Int_t TPadPainter::CreateDrawable(UInt_t w, UInt_t h)
{
   // Create a gVirtualX Pixmap.

   return gVirtualX->OpenPixmap(Int_t(w), Int_t(h));
}

//______________________________________________________________________________
void TPadPainter::ClearDrawable()
{
   // Clear the current gVirtualX window.

   gVirtualX->ClearWindow();
}

//______________________________________________________________________________
void TPadPainter::CopyDrawable(Int_t id, Int_t px, Int_t py)
{
   // Copy a gVirtualX pixmap.

   gVirtualX->CopyPixmap(id, px, py);
}

//______________________________________________________________________________
void TPadPainter::DestroyDrawable()
{
   // Close the current gVirtualX pixmap.

   gVirtualX->ClosePixmap();
}

//______________________________________________________________________________
void TPadPainter::SelectDrawable(Int_t device)
{
   // Select the window in which the graphics will go.

   gVirtualX->SelectWindow(device);
}

//______________________________________________________________________________
void TPadPainter::DrawLine(Double_t x1, Double_t y1, Double_t x2, Double_t y2)
{
   // Paint a simple line.

   Int_t px1 = gPad->XtoPixel(x1);
   Int_t px2 = gPad->XtoPixel(x2);
   Int_t py1 = gPad->YtoPixel(y1);
   Int_t py2 = gPad->YtoPixel(y2);

   gVirtualX->DrawLine(px1, py1, px2, py2);
}

//______________________________________________________________________________
void TPadPainter::DrawLineNDC(Double_t u1, Double_t v1, Double_t u2, Double_t v2)
{
   // Paint a simple line in normalized coordinates.

   Int_t px1 = gPad->UtoPixel(u1);
   Int_t py1 = gPad->VtoPixel(v1);
   Int_t px2 = gPad->UtoPixel(u2);
   Int_t py2 = gPad->VtoPixel(v2);
   gVirtualX->DrawLine(px1, py1, px2, py2);
}

//______________________________________________________________________________
void TPadPainter::DrawBox(Double_t x1, Double_t y1, Double_t x2, Double_t y2, EBoxMode mode)
{
   // Paint a simple box.

   Int_t px1 = gPad->XtoPixel(x1);
   Int_t px2 = gPad->XtoPixel(x2);
   Int_t py1 = gPad->YtoPixel(y1);
   Int_t py2 = gPad->YtoPixel(y2);

   // Box width must be at least one pixel
   if (TMath::Abs(px2-px1) < 1) px2 = px1+1;
   if (TMath::Abs(py1-py2) < 1) py1 = py2+1;

   gVirtualX->DrawBox(px1,py1,px2,py2,(TVirtualX::EBoxMode)mode);
}

//______________________________________________________________________________
void TPadPainter::DrawFillArea(Int_t n, const Double_t *x, const Double_t *y)
{
   // Paint filled area.

   TPoint *pxy = &gPXY[0];
   if (n >= kPXY) pxy = new TPoint[n+1]; if (!pxy) return;
   Int_t fillstyle = gVirtualX->GetFillStyle();
   for (Int_t i=0; i<n; i++) {
      pxy[i].fX = gPad->XtoPixel(x[i]);
      pxy[i].fY = gPad->YtoPixel(y[i]);
   }
   if (fillstyle == 0) {
      pxy[n].fX = pxy[0].fX;
      pxy[n].fY = pxy[0].fY;
      gVirtualX->DrawFillArea(n+1,pxy);
   } else {
      gVirtualX->DrawFillArea(n,pxy);
   }
   if (n >= kPXY) delete [] pxy;
}

//______________________________________________________________________________
void TPadPainter::DrawFillArea(Int_t n, const Float_t *x, const Float_t *y)
{
   // Paint filled area.

   TPoint *pxy = &gPXY[0];
   if (n >= kPXY) pxy = new TPoint[n+1]; if (!pxy) return;
   Int_t fillstyle = gVirtualX->GetFillStyle();
   for (Int_t i=0; i<n; i++) {
      pxy[i].fX = gPad->XtoPixel(x[i]);
      pxy[i].fY = gPad->YtoPixel(y[i]);
   }
   if (fillstyle == 0) {
      pxy[n].fX = pxy[0].fX;
      pxy[n].fY = pxy[0].fY;
      gVirtualX->DrawFillArea(n+1,pxy);
   } else {
      gVirtualX->DrawFillArea(n,pxy);
   }
   if (n >= kPXY) delete [] pxy;
}

//______________________________________________________________________________
void TPadPainter::DrawPolyLine(Int_t n, const Double_t *x, const Double_t *y)
{
   // Paint polyline.

   TPoint *pxy = &gPXY[0];
   if (n >= kPXY) pxy = new TPoint[n+1]; if (!pxy) return;
   for (Int_t i=0; i<n; i++) {
      pxy[i].fX = gPad->XtoPixel(x[i]);
      pxy[i].fY = gPad->YtoPixel(y[i]);
   }
   gVirtualX->DrawPolyLine(n,pxy);
   if (n >= kPXY) delete [] pxy;
}

//______________________________________________________________________________
void TPadPainter::DrawPolyLine(Int_t n, const Float_t *x, const Float_t *y)
{
   // Paint polyline.

   TPoint *pxy = &gPXY[0];
   if (n >= kPXY) pxy = new TPoint[n+1]; if (!pxy) return;
   for (Int_t i=0; i<n; i++) {
      pxy[i].fX = gPad->XtoPixel(x[i]);
      pxy[i].fY = gPad->YtoPixel(y[i]);
   }
   gVirtualX->DrawPolyLine(n,pxy);
   if (n >= kPXY) delete [] pxy;
}

//______________________________________________________________________________
void TPadPainter::DrawPolyLineNDC(Int_t n, const Double_t *u, const Double_t *v)
{
   // Paint polyline in normalized coordinates.

   TPoint *pxy = &gPXY[0];
   if (n >= kPXY) pxy = new TPoint[n+1]; if (!pxy) return;
   for (Int_t i=0; i<n; i++) {
      pxy[i].fX = gPad->UtoPixel(u[i]);
      pxy[i].fY = gPad->VtoPixel(v[i]);
   }
   gVirtualX->DrawPolyLine(n,pxy);
   if (n >= kPXY) delete [] pxy;
}

//______________________________________________________________________________
void TPadPainter::DrawPolyMarker(Int_t n, const Double_t *x, const Double_t *y)
{
   // Paint polymarker.

   TPoint *pxy = &gPXY[0];
   if (n >= kPXY) pxy = new TPoint[n+1]; if (!pxy) return;
   for (Int_t i=0; i<n; i++) {
      pxy[i].fX = gPad->XtoPixel(x[i]);
      pxy[i].fY = gPad->YtoPixel(y[i]);
   }
   gVirtualX->DrawPolyMarker(n,pxy);
   if (n >= kPXY)   delete [] pxy;
}

//______________________________________________________________________________
void TPadPainter::DrawPolyMarker(Int_t n, const Float_t *x, const Float_t *y)
{
   // Paint polymarker.

   TPoint *pxy = &gPXY[0];
   if (n >= kPXY) pxy = new TPoint[n+1]; if (!pxy) return;
   for (Int_t i=0; i<n; i++) {
      pxy[i].fX = gPad->XtoPixel(x[i]);
      pxy[i].fY = gPad->YtoPixel(y[i]);
   }
   gVirtualX->DrawPolyMarker(n,pxy);
   if (n >= kPXY)   delete [] pxy;
}

//______________________________________________________________________________
void TPadPainter::DrawText(Double_t x, Double_t y, const char *text, ETextMode mode)
{
   // Paint text.

   Int_t px = gPad->XtoPixel(x);
   Int_t py = gPad->YtoPixel(y);
   Double_t angle = GetTextAngle();
   Double_t mgn = GetTextMagnitude();
   gVirtualX->DrawText(px, py, angle, mgn, text, (TVirtualX::ETextMode)mode);
}

//______________________________________________________________________________
void TPadPainter::DrawTextNDC(Double_t u, Double_t v, const char *text, ETextMode mode)
{
   // Paint text in normalized coordinates.

   Int_t px = gPad->UtoPixel(u);
   Int_t py = gPad->VtoPixel(v);
   Double_t angle = GetTextAngle();
   Double_t mgn = GetTextMagnitude();
   gVirtualX->DrawText(px, py, angle, mgn, text, (TVirtualX::ETextMode)mode);
}

//______________________________________________________________________________
void TPadPainter::SaveImage(TVirtualPad *pad, const char *fileName, Int_t type) const
{
   // Save the image displayed in the canvas pointed by "pad" into a
   // binary file.

   if (type == TImage::kGif) {
      gVirtualX->WriteGIF((char*)fileName);
   } else {
      TImage *img = TImage::Create();
      img->FromPad(pad);
      img->WriteImage(fileName, (TImage::EImageFileTypes)type);
      delete img;
   }
}
<commit_msg>Fix coverity report #33283<commit_after>#include "TPad.h"
#include "TPoint.h"
#include "TPadPainter.h"
#include "TVirtualX.h"
#include "TImage.h"

// Local scratch buffer for screen points, faster than allocating buffer on heap
const Int_t kPXY = 1002;
static TPoint gPXY[kPXY];

ClassImp(TPadPainter)

//______________________________________________________________________________
TPadPainter::TPadPainter()
{
   //Empty ctor. Here only because of explicit copy ctor.
}

/*
Line/fill/etc. attributes can be set inside TPad, but not only where:
many of them are set by base sub-objects of 2d primitives
(2d primitives usually inherit TAttLine or TAttFill etc.).  And these sub-objects
call gVirtualX->SetLineWidth ... etc. So, if I save some attributes in my painter,
it will be mess - at any moment I do not know, where to take line attribute - from
gVirtualX or from my own member. So! All attributed, _ALL_ go to/from gVirtualX.
*/

//______________________________________________________________________________
Color_t TPadPainter::GetLineColor() const
{
   // Delegate to gVirtualX.

   return gVirtualX->GetLineColor();
}

//______________________________________________________________________________
Style_t TPadPainter::GetLineStyle() const
{
   // Delegate to gVirtualX.

   return gVirtualX->GetLineStyle();
}

//______________________________________________________________________________
Width_t TPadPainter::GetLineWidth() const
{
   // Delegate to gVirtualX.

   return gVirtualX->GetLineWidth();
}

//______________________________________________________________________________
void TPadPainter::SetLineColor(Color_t lcolor)
{
   // Delegate to gVirtualX.

   gVirtualX->SetLineColor(lcolor);
}

//______________________________________________________________________________
void TPadPainter::SetLineStyle(Style_t lstyle)
{
   // Delegate to gVirtualX.

   gVirtualX->SetLineStyle(lstyle);
}

//______________________________________________________________________________
void TPadPainter::SetLineWidth(Width_t lwidth)
{
   // Delegate to gVirtualX.

   gVirtualX->SetLineWidth(lwidth);
}

//______________________________________________________________________________
Color_t TPadPainter::GetFillColor() const
{
   // Delegate to gVirtualX.

   return gVirtualX->GetFillColor();
}

//______________________________________________________________________________
Style_t TPadPainter::GetFillStyle() const
{
   // Delegate to gVirtualX.

   return gVirtualX->GetFillStyle();
}

//______________________________________________________________________________
Bool_t TPadPainter::IsTransparent() const
{
   // Delegate to gVirtualX.

   //IsTransparent is implemented as inline function in TAttFill.
   return gVirtualX->IsTransparent();
}

//______________________________________________________________________________
void TPadPainter::SetFillColor(Color_t fcolor)
{
   // Delegate to gVirtualX.

   gVirtualX->SetFillColor(fcolor);
}

//______________________________________________________________________________
void TPadPainter::SetFillStyle(Style_t fstyle)
{
   // Delegate to gVirtualX.

   gVirtualX->SetFillStyle(fstyle);
}

//______________________________________________________________________________
void TPadPainter::SetOpacity(Int_t percent)
{
   // Delegate to gVirtualX.

   gVirtualX->SetOpacity(percent);
}

//______________________________________________________________________________
Short_t TPadPainter::GetTextAlign() const
{
   // Delegate to gVirtualX.

   return gVirtualX->GetTextAlign();
}

//______________________________________________________________________________
Float_t TPadPainter::GetTextAngle() const
{
   // Delegate to gVirtualX.

   return gVirtualX->GetTextAngle();
}

//______________________________________________________________________________
Color_t TPadPainter::GetTextColor() const
{
   // Delegate to gVirtualX.

   return gVirtualX->GetTextColor();
}

//______________________________________________________________________________
Font_t TPadPainter::GetTextFont() const
{
   // Delegate to gVirtualX.

   return gVirtualX->GetTextFont();
}

//______________________________________________________________________________
Float_t TPadPainter::GetTextSize() const
{
   // Delegate to gVirtualX.

   return gVirtualX->GetTextSize();
}

//______________________________________________________________________________
Float_t TPadPainter::GetTextMagnitude() const
{
   // Delegate to gVirtualX.

   return gVirtualX->GetTextMagnitude();
}

//______________________________________________________________________________
void TPadPainter::SetTextAlign(Short_t align)
{
   // Delegate to gVirtualX.

   gVirtualX->SetTextAlign(align);
}

//______________________________________________________________________________
void TPadPainter::SetTextAngle(Float_t tangle)
{
   // Delegate to gVirtualX.

   gVirtualX->SetTextAngle(tangle);
}

//______________________________________________________________________________
void TPadPainter::SetTextColor(Color_t tcolor)
{
   // Delegate to gVirtualX.

   gVirtualX->SetTextColor(tcolor);
}

//______________________________________________________________________________
void TPadPainter::SetTextFont(Font_t tfont)
{
   // Delegate to gVirtualX.

   gVirtualX->SetTextFont(tfont);
}

//______________________________________________________________________________
void TPadPainter::SetTextSize(Float_t tsize)
{
   // Delegate to gVirtualX.

   gVirtualX->SetTextSize(tsize);
}

//______________________________________________________________________________
void TPadPainter::SetTextSizePixels(Int_t npixels)
{
   // Delegate to gVirtualX.

   gVirtualX->SetTextSizePixels(npixels);
}

//______________________________________________________________________________
Int_t TPadPainter::CreateDrawable(UInt_t w, UInt_t h)
{
   // Create a gVirtualX Pixmap.

   return gVirtualX->OpenPixmap(Int_t(w), Int_t(h));
}

//______________________________________________________________________________
void TPadPainter::ClearDrawable()
{
   // Clear the current gVirtualX window.

   gVirtualX->ClearWindow();
}

//______________________________________________________________________________
void TPadPainter::CopyDrawable(Int_t id, Int_t px, Int_t py)
{
   // Copy a gVirtualX pixmap.

   gVirtualX->CopyPixmap(id, px, py);
}

//______________________________________________________________________________
void TPadPainter::DestroyDrawable()
{
   // Close the current gVirtualX pixmap.

   gVirtualX->ClosePixmap();
}

//______________________________________________________________________________
void TPadPainter::SelectDrawable(Int_t device)
{
   // Select the window in which the graphics will go.

   gVirtualX->SelectWindow(device);
}

//______________________________________________________________________________
void TPadPainter::DrawLine(Double_t x1, Double_t y1, Double_t x2, Double_t y2)
{
   // Paint a simple line.

   Int_t px1 = gPad->XtoPixel(x1);
   Int_t px2 = gPad->XtoPixel(x2);
   Int_t py1 = gPad->YtoPixel(y1);
   Int_t py2 = gPad->YtoPixel(y2);

   gVirtualX->DrawLine(px1, py1, px2, py2);
}

//______________________________________________________________________________
void TPadPainter::DrawLineNDC(Double_t u1, Double_t v1, Double_t u2, Double_t v2)
{
   // Paint a simple line in normalized coordinates.

   Int_t px1 = gPad->UtoPixel(u1);
   Int_t py1 = gPad->VtoPixel(v1);
   Int_t px2 = gPad->UtoPixel(u2);
   Int_t py2 = gPad->VtoPixel(v2);
   gVirtualX->DrawLine(px1, py1, px2, py2);
}

//______________________________________________________________________________
void TPadPainter::DrawBox(Double_t x1, Double_t y1, Double_t x2, Double_t y2, EBoxMode mode)
{
   // Paint a simple box.

   Int_t px1 = gPad->XtoPixel(x1);
   Int_t px2 = gPad->XtoPixel(x2);
   Int_t py1 = gPad->YtoPixel(y1);
   Int_t py2 = gPad->YtoPixel(y2);

   // Box width must be at least one pixel
   if (TMath::Abs(px2-px1) < 1) px2 = px1+1;
   if (TMath::Abs(py1-py2) < 1) py1 = py2+1;

   gVirtualX->DrawBox(px1,py1,px2,py2,(TVirtualX::EBoxMode)mode);
}

//______________________________________________________________________________
void TPadPainter::DrawFillArea(Int_t n, const Double_t *x, const Double_t *y)
{
   // Paint filled area.

   TPoint *pxy = &gPXY[0];
   if (n >= kPXY) pxy = new TPoint[n+1]; if (!pxy) return;
   Int_t fillstyle = gVirtualX->GetFillStyle();
   for (Int_t i=0; i<n; i++) {
      pxy[i].fX = gPad->XtoPixel(x[i]);
      pxy[i].fY = gPad->YtoPixel(y[i]);
   }
   if (fillstyle == 0) {
      pxy[n].fX = pxy[0].fX;
      pxy[n].fY = pxy[0].fY;
      gVirtualX->DrawFillArea(n+1,pxy);
   } else {
      gVirtualX->DrawFillArea(n,pxy);
   }
   if (n >= kPXY) delete [] pxy;
}

//______________________________________________________________________________
void TPadPainter::DrawFillArea(Int_t n, const Float_t *x, const Float_t *y)
{
   // Paint filled area.

   TPoint *pxy = &gPXY[0];
   if (n >= kPXY) pxy = new TPoint[n+1]; if (!pxy) return;
   Int_t fillstyle = gVirtualX->GetFillStyle();
   for (Int_t i=0; i<n; i++) {
      pxy[i].fX = gPad->XtoPixel(x[i]);
      pxy[i].fY = gPad->YtoPixel(y[i]);
   }
   if (fillstyle == 0) {
      pxy[n].fX = pxy[0].fX;
      pxy[n].fY = pxy[0].fY;
      gVirtualX->DrawFillArea(n+1,pxy);
   } else {
      gVirtualX->DrawFillArea(n,pxy);
   }
   if (n >= kPXY) delete [] pxy;
}

//______________________________________________________________________________
void TPadPainter::DrawPolyLine(Int_t n, const Double_t *x, const Double_t *y)
{
   // Paint polyline.

   TPoint *pxy = &gPXY[0];
   if (n >= kPXY) pxy = new TPoint[n+1]; if (!pxy) return;
   for (Int_t i=0; i<n; i++) {
      pxy[i].fX = gPad->XtoPixel(x[i]);
      pxy[i].fY = gPad->YtoPixel(y[i]);
   }
   gVirtualX->DrawPolyLine(n,pxy);
   if (n >= kPXY) delete [] pxy;
}

//______________________________________________________________________________
void TPadPainter::DrawPolyLine(Int_t n, const Float_t *x, const Float_t *y)
{
   // Paint polyline.

   TPoint *pxy = &gPXY[0];
   if (n >= kPXY) pxy = new TPoint[n+1]; if (!pxy) return;
   for (Int_t i=0; i<n; i++) {
      pxy[i].fX = gPad->XtoPixel(x[i]);
      pxy[i].fY = gPad->YtoPixel(y[i]);
   }
   gVirtualX->DrawPolyLine(n,pxy);
   if (n >= kPXY) delete [] pxy;
}

//______________________________________________________________________________
void TPadPainter::DrawPolyLineNDC(Int_t n, const Double_t *u, const Double_t *v)
{
   // Paint polyline in normalized coordinates.

   TPoint *pxy = &gPXY[0];
   if (n >= kPXY) pxy = new TPoint[n+1]; if (!pxy) return;
   for (Int_t i=0; i<n; i++) {
      pxy[i].fX = gPad->UtoPixel(u[i]);
      pxy[i].fY = gPad->VtoPixel(v[i]);
   }
   gVirtualX->DrawPolyLine(n,pxy);
   if (n >= kPXY) delete [] pxy;
}

//______________________________________________________________________________
void TPadPainter::DrawPolyMarker(Int_t n, const Double_t *x, const Double_t *y)
{
   // Paint polymarker.

   TPoint *pxy = &gPXY[0];
   if (n >= kPXY) pxy = new TPoint[n+1]; if (!pxy) return;
   for (Int_t i=0; i<n; i++) {
      pxy[i].fX = gPad->XtoPixel(x[i]);
      pxy[i].fY = gPad->YtoPixel(y[i]);
   }
   gVirtualX->DrawPolyMarker(n,pxy);
   if (n >= kPXY)   delete [] pxy;
}

//______________________________________________________________________________
void TPadPainter::DrawPolyMarker(Int_t n, const Float_t *x, const Float_t *y)
{
   // Paint polymarker.

   TPoint *pxy = &gPXY[0];
   if (n >= kPXY) pxy = new TPoint[n+1]; if (!pxy) return;
   for (Int_t i=0; i<n; i++) {
      pxy[i].fX = gPad->XtoPixel(x[i]);
      pxy[i].fY = gPad->YtoPixel(y[i]);
   }
   gVirtualX->DrawPolyMarker(n,pxy);
   if (n >= kPXY)   delete [] pxy;
}

//______________________________________________________________________________
void TPadPainter::DrawText(Double_t x, Double_t y, const char *text, ETextMode mode)
{
   // Paint text.

   Int_t px = gPad->XtoPixel(x);
   Int_t py = gPad->YtoPixel(y);
   Double_t angle = GetTextAngle();
   Double_t mgn = GetTextMagnitude();
   gVirtualX->DrawText(px, py, angle, mgn, text, (TVirtualX::ETextMode)mode);
}

//______________________________________________________________________________
void TPadPainter::DrawTextNDC(Double_t u, Double_t v, const char *text, ETextMode mode)
{
   // Paint text in normalized coordinates.

   Int_t px = gPad->UtoPixel(u);
   Int_t py = gPad->VtoPixel(v);
   Double_t angle = GetTextAngle();
   Double_t mgn = GetTextMagnitude();
   gVirtualX->DrawText(px, py, angle, mgn, text, (TVirtualX::ETextMode)mode);
}

//______________________________________________________________________________
void TPadPainter::SaveImage(TVirtualPad *pad, const char *fileName, Int_t type) const
{
   // Save the image displayed in the canvas pointed by "pad" into a
   // binary file.

   if (type == TImage::kGif) {
      gVirtualX->WriteGIF((char*)fileName);
   } else {
      TImage *img = TImage::Create();
      if (img) {
         img->FromPad(pad);
         img->WriteImage(fileName, (TImage::EImageFileTypes)type);
         delete img;
      }
   }
}
<|endoftext|>


<commit_before>// @(#)root/eve:$Id$
// Author: Matevz Tadel 2007

/*************************************************************************
 * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "TEveGeoShape.h"
#include "TEveTrans.h"
#include "TEveManager.h"
#include "TEvePolygonSetProjected.h"
#include "TEveProjections.h"
#include "TEveProjectionManager.h"

#include "TEveGeoShapeExtract.h"
#include "TEveGeoPolyShape.h"

#include "TROOT.h"
#include "TBuffer3D.h"
#include "TVirtualViewer3D.h"
#include "TColor.h"
#include "TFile.h"

#include "TGeoShape.h"
#include "TGeoVolume.h"
#include "TGeoNode.h"
#include "TGeoShapeAssembly.h"
#include "TGeoCompositeShape.h"
#include "TGeoManager.h"
#include "TGeoMatrix.h"
#include "TVirtualGeoPainter.h"

namespace
{
TGeoManager* init_geo_mangeur()
{
   // Create a phony geo manager that can be used for storing free
   // shapes. Otherwise shapes register themselves to current
   // geo-manager (or even create one).

   TGeoManager* old = gGeoManager;
   gGeoManager = 0;
   TGeoManager* mgr = new TGeoManager();
   mgr->SetNameTitle("TEveGeoShape::fgGeoMangeur",
                     "Static geo manager used for wrapped TGeoShapes.");
   gGeoManager = old;
   return mgr;
}
}

//==============================================================================
//==============================================================================
// TEveGeoShape
//==============================================================================

//______________________________________________________________________________
//
// Wrapper for TGeoShape with absolute positioning and color
// attributes allowing display of extracted TGeoShape's (without an
// active TGeoManager) and simplified geometries (needed for non-linear
// projections).
//
// TGeoCompositeShapes and TGeoAssemblies are supported.
//
// If fNSegments data-member is < 2 (0 by default), the default number of
// segments is used for tesselation and special GL objects are
// instantiated for selected shapes (spheres, tubes). If fNSegments is > 2,
// it gets forwarded to geo-manager and this tesselation detail is
// used when creating the buffer passed to GL.

ClassImp(TEveGeoShape);

TGeoManager* TEveGeoShape::fgGeoMangeur = init_geo_mangeur();

//______________________________________________________________________________
TGeoManager* TEveGeoShape::GetGeoMangeur()
{
   // Return static geo-manager that is used intenally to make shapes
   // lead a happy life.
   // Set gGeoManager to this object when creating TGeoShapes to be
   // passed into TEveGeoShapes.

   return fgGeoMangeur;
}

//______________________________________________________________________________
TEveGeoShape::TEveGeoShape(const char* name, const char* title) :
   TEveElement   (fColor),
   TNamed        (name, title),
   fColor        (0),
   fNSegments    (0),
   fShape        (0)
{
   // Constructor.

   fCanEditMainColor        = kTRUE;
   fCanEditMainTransparency = kTRUE;
   InitMainTrans();
}

//______________________________________________________________________________
TEveGeoShape::~TEveGeoShape()
{
   // Destructor.

   SetShape(0);
}

//______________________________________________________________________________
void TEveGeoShape::SetShape(TGeoShape* s)
{
   // Set TGeoShape shown by this object.

   TEveGeoManagerHolder gmgr(fgGeoMangeur);

   if (fShape) {
      fShape->SetUniqueID(fShape->GetUniqueID() - 1);
      if (fShape->GetUniqueID() == 0)
         delete fShape;
   }
   fShape = s;
   if (fShape) {
      fShape->SetUniqueID(fShape->GetUniqueID() + 1);
   }
}

/******************************************************************************/

//______________________________________________________________________________
void TEveGeoShape::Paint(Option_t* /*option*/)
{
   // Paint object.

   static const TEveException eh("TEveGeoShape::Paint ");

   if (fShape == 0)
      return;

   TEveGeoManagerHolder gmgr(fgGeoMangeur, fNSegments);

   TBuffer3D& buff = (TBuffer3D&) fShape->GetBuffer3D
      (TBuffer3D::kCore, kFALSE);

   buff.fID           = this;
   buff.fColor        = GetMainColor();
   buff.fTransparency = GetMainTransparency();
   RefMainTrans().SetBuffer3D(buff);
   buff.fLocalFrame   = kTRUE; // Always enforce local frame (no geo manager).

   Int_t sections = TBuffer3D::kBoundingBox | TBuffer3D::kShapeSpecific;
   if (fNSegments > 2)
      sections |= TBuffer3D::kRawSizes | TBuffer3D::kRaw;
   fShape->GetBuffer3D(sections, kTRUE);

   Int_t reqSec = gPad->GetViewer3D()->AddObject(buff);

   if (reqSec != TBuffer3D::kNone) {
      // This shouldn't happen, but I suspect it does sometimes.
      if (reqSec & TBuffer3D::kCore)
         Warning(eh, "Core section required again for shape='%s'. This shouldn't happen.", GetName());
      fShape->GetBuffer3D(reqSec, kTRUE);
      reqSec = gPad->GetViewer3D()->AddObject(buff);
   }

   if (reqSec != TBuffer3D::kNone)
      Warning(eh, "Extra section required: reqSec=%d, shape=%s.", reqSec, GetName());
}

/******************************************************************************/

//______________________________________________________________________________
void TEveGeoShape::Save(const char* file, const char* name)
{
   // Save the shape tree as TEveGeoShapeExtract.
   // File is always recreated.
   // This function is obsolete, use SaveExtractInstead().

   Warning("Save()", "This function is deprecated, use SaveExtract() instead.");
   SaveExtract(file, name);
}

//______________________________________________________________________________
void TEveGeoShape::SaveExtract(const char* file, const char* name)
{
   // Save the shape tree as TEveGeoShapeExtract.
   // File is always recreated.

   TEveGeoShapeExtract* gse = DumpShapeTree(this, 0);

   TFile f(file, "RECREATE");
   gse->Write(name);
   f.Close();
}

//______________________________________________________________________________
void TEveGeoShape::WriteExtract(const char* name)
{
   // Write the shape tree as TEveGeoShapeExtract to current directory.

   TEveGeoShapeExtract* gse = DumpShapeTree(this, 0);
   gse->Write(name);
}

/******************************************************************************/

//______________________________________________________________________________
TEveGeoShapeExtract* TEveGeoShape::DumpShapeTree(TEveGeoShape* gsre,
                                                 TEveGeoShapeExtract* parent)
{
   // Export this shape and its descendants into a geoshape-extract.

   TEveGeoShapeExtract* she = new TEveGeoShapeExtract(gsre->GetName(), gsre->GetTitle());
   she->SetTrans(gsre->RefMainTrans().Array());
   Int_t ci = gsre->GetColor();
   TColor* c = gROOT->GetColor(ci);
   Float_t rgba[4] = {1, 0, 0, 1 - gsre->GetMainTransparency()/100.};
   if (c)
   {
      rgba[0] = c->GetRed();
      rgba[1] = c->GetGreen();
      rgba[2] = c->GetBlue();
   }
   she->SetRGBA(rgba);
   she->SetRnrSelf(gsre->GetRnrSelf());
   she->SetRnrElements(gsre->GetRnrChildren());
   she->SetShape(gsre->GetShape());
   if (gsre->HasChildren())
   {
      TList* ele = new TList();
      she->SetElements(ele);
      she->GetElements()->SetOwner(true);
      TEveElement::List_i i = gsre->BeginChildren();
      while (i != gsre->EndChildren()) {
         TEveGeoShape* l = dynamic_cast<TEveGeoShape*>(*i);
         DumpShapeTree(l, she);
         i++;
      }
   }
   if (parent)
      parent->GetElements()->Add(she);

   return she;
}

//______________________________________________________________________________
TEveGeoShape* TEveGeoShape::ImportShapeExtract(TEveGeoShapeExtract* gse,
                                               TEveElement*         parent)
{
   // Import a shape extract 'gse' under element 'parent'.

   TEveGeoManagerHolder gmgr(fgGeoMangeur);
   TEveManager::TRedrawDisabler redrawOff(gEve);
   TEveGeoShape* gsre = SubImportShapeExtract(gse, parent);
   gsre->ElementChanged();
   return gsre;
}

//______________________________________________________________________________
TEveGeoShape* TEveGeoShape::SubImportShapeExtract(TEveGeoShapeExtract* gse,
                                                  TEveElement*         parent)
{
   // Recursive version for importing a shape extract tree.

   TEveGeoShape* gsre = new TEveGeoShape(gse->GetName(), gse->GetTitle());
   gsre->RefMainTrans().SetFromArray(gse->GetTrans());
   const Float_t* rgba = gse->GetRGBA();
   gsre->SetMainColorRGB(rgba[0], rgba[1], rgba[2]);
   gsre->SetMainAlpha(rgba[3]);
   gsre->SetRnrSelf(gse->GetRnrSelf());
   gsre->SetRnrChildren(gse->GetRnrElements());
   gsre->SetShape(gse->GetShape());

   if (parent)
      parent->AddElement(gsre);

   if (gse->HasElements())
   {
      TIter next(gse->GetElements());
      TEveGeoShapeExtract* chld;
      while ((chld = (TEveGeoShapeExtract*) next()) != 0)
         SubImportShapeExtract(chld, gsre);
   }

   return gsre;
}

/******************************************************************************/

//______________________________________________________________________________
TClass* TEveGeoShape::ProjectedClass(const TEveProjection* p) const
{
   // Return class for projected objects:
   //  - 2D projections: TEvePolygonSetProjected,
   //  - 3D projections: TEveGeoShapeProjected.
   // Virtual from TEveProjectable.

   if (p->Is2D())
      return TEvePolygonSetProjected::Class();
   else
      return TEveGeoShapeProjected::Class();
}

/******************************************************************************/

//______________________________________________________________________________
TBuffer3D* TEveGeoShape::MakeBuffer3D()
{
   // Create a TBuffer3D suitable for presentation of the shape.
   // Transformation matrix is also applied.

   if (fShape == 0) return 0;

   if (dynamic_cast<TGeoShapeAssembly*>(fShape)) {
      // !!!! TGeoShapeAssembly makes a bad TBuffer3D
      return 0;
   }

   TEveGeoManagerHolder gmgr(fgGeoMangeur, fNSegments);

   TBuffer3D* buff  = fShape->MakeBuffer3D();
   TEveTrans& mx    = RefMainTrans();
   if (mx.GetUseTrans())
   {
      Int_t n = buff->NbPnts();
      Double_t* pnts = buff->fPnts;
      for(Int_t k = 0; k < n; ++k)
      {
         mx.MultiplyIP(&pnts[3*k]);
      }
   }
   return buff;
}

//==============================================================================
//==============================================================================
// TEveGeoShapeProjected
//==============================================================================

//______________________________________________________________________________
//
// A 3D projected TEveGeoShape.

ClassImp(TEveGeoShapeProjected);

//______________________________________________________________________________
TEveGeoShapeProjected::TEveGeoShapeProjected() :
   TEveElementList("TEveGeoShapeProjected", "", kTRUE),
   fBuff(0)
{
   // Constructor.
}

//______________________________________________________________________________
void TEveGeoShapeProjected::SetDepthLocal(Float_t /*d*/)
{
   // This should never be called as this class is only used for 3D
   // projections.
   // The implementation is required as this metod is abstract.
   // Just emits a warning if called.

   Warning("SetDepthLocal", "This function only exists to fulfill an abstract interface.");
}

//______________________________________________________________________________
void TEveGeoShapeProjected::SetProjection(TEveProjectionManager* mng,
                                          TEveProjectable* model)
{
   // This is virtual method from base-class TEveProjected.

   TEveProjected::SetProjection(mng, model);

   CopyVizParams(dynamic_cast<TEveElement*>(model));
}

//______________________________________________________________________________
void TEveGeoShapeProjected::UpdateProjection()
{
   // This is virtual method from base-class TEveProjected.

   TEveGeoShape   *gre = dynamic_cast<TEveGeoShape*>(fProjectable);
   TEveProjection *prj = fManager->GetProjection();

   delete fBuff;
   fBuff = gre->MakeBuffer3D();

   if (fBuff)
   {
      fBuff->SetSectionsValid(TBuffer3D::kCore | TBuffer3D::kRawSizes | TBuffer3D::kRaw);

      Double_t *p = fBuff->fPnts;
      for (UInt_t i = 0; i < fBuff->NbPnts(); ++i, p+=3)
      {
         prj->ProjectPointdv(p, 0);
      }
   }

   ResetBBox();
}

//______________________________________________________________________________
void TEveGeoShapeProjected::ComputeBBox()
{
   // Override of virtual method from TAttBBox.

   if (fBuff && fBuff->NbPnts() > 0)
   {
      BBoxInit();

      Double_t *p = fBuff->fPnts;
      for (UInt_t i = 0; i < fBuff->NbPnts(); ++i, p+=3)
      {
         BBoxCheckPoint(p[0], p[1], p[2]);
      }
   }
   else
   {
      BBoxZero();
   }
}

//______________________________________________________________________________
void TEveGeoShapeProjected::Paint(Option_t* /*option*/)
{
   // Paint object.

   static const TEveException eh("TEveGeoShapeProjected::Paint ");

   if (fBuff == 0)
      return;

   TBuffer3D &buff = *fBuff;

   buff.fID           = this;
   buff.fColor        = GetMainColor();
   buff.fTransparency = GetMainTransparency();
   buff.fLocalFrame   = kTRUE;

   Int_t reqSec = gPad->GetViewer3D()->AddObject(buff);

   if (reqSec != TBuffer3D::kNone)
      Warning(eh, "Extra section required: reqSec=%d, shape=%s.", reqSec, GetName());
}
<commit_msg>Copy color to projection, too.<commit_after>// @(#)root/eve:$Id$
// Author: Matevz Tadel 2007

/*************************************************************************
 * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "TEveGeoShape.h"
#include "TEveTrans.h"
#include "TEveManager.h"
#include "TEvePolygonSetProjected.h"
#include "TEveProjections.h"
#include "TEveProjectionManager.h"

#include "TEveGeoShapeExtract.h"
#include "TEveGeoPolyShape.h"

#include "TROOT.h"
#include "TBuffer3D.h"
#include "TVirtualViewer3D.h"
#include "TColor.h"
#include "TFile.h"

#include "TGeoShape.h"
#include "TGeoVolume.h"
#include "TGeoNode.h"
#include "TGeoShapeAssembly.h"
#include "TGeoCompositeShape.h"
#include "TGeoManager.h"
#include "TGeoMatrix.h"
#include "TVirtualGeoPainter.h"

namespace
{
TGeoManager* init_geo_mangeur()
{
   // Create a phony geo manager that can be used for storing free
   // shapes. Otherwise shapes register themselves to current
   // geo-manager (or even create one).

   TGeoManager* old = gGeoManager;
   gGeoManager = 0;
   TGeoManager* mgr = new TGeoManager();
   mgr->SetNameTitle("TEveGeoShape::fgGeoMangeur",
                     "Static geo manager used for wrapped TGeoShapes.");
   gGeoManager = old;
   return mgr;
}
}

//==============================================================================
//==============================================================================
// TEveGeoShape
//==============================================================================

//______________________________________________________________________________
//
// Wrapper for TGeoShape with absolute positioning and color
// attributes allowing display of extracted TGeoShape's (without an
// active TGeoManager) and simplified geometries (needed for non-linear
// projections).
//
// TGeoCompositeShapes and TGeoAssemblies are supported.
//
// If fNSegments data-member is < 2 (0 by default), the default number of
// segments is used for tesselation and special GL objects are
// instantiated for selected shapes (spheres, tubes). If fNSegments is > 2,
// it gets forwarded to geo-manager and this tesselation detail is
// used when creating the buffer passed to GL.

ClassImp(TEveGeoShape);

TGeoManager* TEveGeoShape::fgGeoMangeur = init_geo_mangeur();

//______________________________________________________________________________
TGeoManager* TEveGeoShape::GetGeoMangeur()
{
   // Return static geo-manager that is used intenally to make shapes
   // lead a happy life.
   // Set gGeoManager to this object when creating TGeoShapes to be
   // passed into TEveGeoShapes.

   return fgGeoMangeur;
}

//______________________________________________________________________________
TEveGeoShape::TEveGeoShape(const char* name, const char* title) :
   TEveElement   (fColor),
   TNamed        (name, title),
   fColor        (0),
   fNSegments    (0),
   fShape        (0)
{
   // Constructor.

   fCanEditMainColor        = kTRUE;
   fCanEditMainTransparency = kTRUE;
   InitMainTrans();
}

//______________________________________________________________________________
TEveGeoShape::~TEveGeoShape()
{
   // Destructor.

   SetShape(0);
}

//______________________________________________________________________________
void TEveGeoShape::SetShape(TGeoShape* s)
{
   // Set TGeoShape shown by this object.

   TEveGeoManagerHolder gmgr(fgGeoMangeur);

   if (fShape) {
      fShape->SetUniqueID(fShape->GetUniqueID() - 1);
      if (fShape->GetUniqueID() == 0)
         delete fShape;
   }
   fShape = s;
   if (fShape) {
      fShape->SetUniqueID(fShape->GetUniqueID() + 1);
   }
}

/******************************************************************************/

//______________________________________________________________________________
void TEveGeoShape::Paint(Option_t* /*option*/)
{
   // Paint object.

   static const TEveException eh("TEveGeoShape::Paint ");

   if (fShape == 0)
      return;

   TEveGeoManagerHolder gmgr(fgGeoMangeur, fNSegments);

   TBuffer3D& buff = (TBuffer3D&) fShape->GetBuffer3D
      (TBuffer3D::kCore, kFALSE);

   buff.fID           = this;
   buff.fColor        = GetMainColor();
   buff.fTransparency = GetMainTransparency();
   RefMainTrans().SetBuffer3D(buff);
   buff.fLocalFrame   = kTRUE; // Always enforce local frame (no geo manager).

   Int_t sections = TBuffer3D::kBoundingBox | TBuffer3D::kShapeSpecific;
   if (fNSegments > 2)
      sections |= TBuffer3D::kRawSizes | TBuffer3D::kRaw;
   fShape->GetBuffer3D(sections, kTRUE);

   Int_t reqSec = gPad->GetViewer3D()->AddObject(buff);

   if (reqSec != TBuffer3D::kNone) {
      // This shouldn't happen, but I suspect it does sometimes.
      if (reqSec & TBuffer3D::kCore)
         Warning(eh, "Core section required again for shape='%s'. This shouldn't happen.", GetName());
      fShape->GetBuffer3D(reqSec, kTRUE);
      reqSec = gPad->GetViewer3D()->AddObject(buff);
   }

   if (reqSec != TBuffer3D::kNone)
      Warning(eh, "Extra section required: reqSec=%d, shape=%s.", reqSec, GetName());
}

/******************************************************************************/

//______________________________________________________________________________
void TEveGeoShape::Save(const char* file, const char* name)
{
   // Save the shape tree as TEveGeoShapeExtract.
   // File is always recreated.
   // This function is obsolete, use SaveExtractInstead().

   Warning("Save()", "This function is deprecated, use SaveExtract() instead.");
   SaveExtract(file, name);
}

//______________________________________________________________________________
void TEveGeoShape::SaveExtract(const char* file, const char* name)
{
   // Save the shape tree as TEveGeoShapeExtract.
   // File is always recreated.

   TEveGeoShapeExtract* gse = DumpShapeTree(this, 0);

   TFile f(file, "RECREATE");
   gse->Write(name);
   f.Close();
}

//______________________________________________________________________________
void TEveGeoShape::WriteExtract(const char* name)
{
   // Write the shape tree as TEveGeoShapeExtract to current directory.

   TEveGeoShapeExtract* gse = DumpShapeTree(this, 0);
   gse->Write(name);
}

/******************************************************************************/

//______________________________________________________________________________
TEveGeoShapeExtract* TEveGeoShape::DumpShapeTree(TEveGeoShape* gsre,
                                                 TEveGeoShapeExtract* parent)
{
   // Export this shape and its descendants into a geoshape-extract.

   TEveGeoShapeExtract* she = new TEveGeoShapeExtract(gsre->GetName(), gsre->GetTitle());
   she->SetTrans(gsre->RefMainTrans().Array());
   Int_t ci = gsre->GetColor();
   TColor* c = gROOT->GetColor(ci);
   Float_t rgba[4] = {1, 0, 0, 1 - gsre->GetMainTransparency()/100.};
   if (c)
   {
      rgba[0] = c->GetRed();
      rgba[1] = c->GetGreen();
      rgba[2] = c->GetBlue();
   }
   she->SetRGBA(rgba);
   she->SetRnrSelf(gsre->GetRnrSelf());
   she->SetRnrElements(gsre->GetRnrChildren());
   she->SetShape(gsre->GetShape());
   if (gsre->HasChildren())
   {
      TList* ele = new TList();
      she->SetElements(ele);
      she->GetElements()->SetOwner(true);
      TEveElement::List_i i = gsre->BeginChildren();
      while (i != gsre->EndChildren()) {
         TEveGeoShape* l = dynamic_cast<TEveGeoShape*>(*i);
         DumpShapeTree(l, she);
         i++;
      }
   }
   if (parent)
      parent->GetElements()->Add(she);

   return she;
}

//______________________________________________________________________________
TEveGeoShape* TEveGeoShape::ImportShapeExtract(TEveGeoShapeExtract* gse,
                                               TEveElement*         parent)
{
   // Import a shape extract 'gse' under element 'parent'.

   TEveGeoManagerHolder gmgr(fgGeoMangeur);
   TEveManager::TRedrawDisabler redrawOff(gEve);
   TEveGeoShape* gsre = SubImportShapeExtract(gse, parent);
   gsre->ElementChanged();
   return gsre;
}

//______________________________________________________________________________
TEveGeoShape* TEveGeoShape::SubImportShapeExtract(TEveGeoShapeExtract* gse,
                                                  TEveElement*         parent)
{
   // Recursive version for importing a shape extract tree.

   TEveGeoShape* gsre = new TEveGeoShape(gse->GetName(), gse->GetTitle());
   gsre->RefMainTrans().SetFromArray(gse->GetTrans());
   const Float_t* rgba = gse->GetRGBA();
   gsre->SetMainColorRGB(rgba[0], rgba[1], rgba[2]);
   gsre->SetMainAlpha(rgba[3]);
   gsre->SetRnrSelf(gse->GetRnrSelf());
   gsre->SetRnrChildren(gse->GetRnrElements());
   gsre->SetShape(gse->GetShape());

   if (parent)
      parent->AddElement(gsre);

   if (gse->HasElements())
   {
      TIter next(gse->GetElements());
      TEveGeoShapeExtract* chld;
      while ((chld = (TEveGeoShapeExtract*) next()) != 0)
         SubImportShapeExtract(chld, gsre);
   }

   return gsre;
}

/******************************************************************************/

//______________________________________________________________________________
TClass* TEveGeoShape::ProjectedClass(const TEveProjection* p) const
{
   // Return class for projected objects:
   //  - 2D projections: TEvePolygonSetProjected,
   //  - 3D projections: TEveGeoShapeProjected.
   // Virtual from TEveProjectable.

   if (p->Is2D())
      return TEvePolygonSetProjected::Class();
   else
      return TEveGeoShapeProjected::Class();
}

/******************************************************************************/

//______________________________________________________________________________
TBuffer3D* TEveGeoShape::MakeBuffer3D()
{
   // Create a TBuffer3D suitable for presentation of the shape.
   // Transformation matrix is also applied.

   if (fShape == 0) return 0;

   if (dynamic_cast<TGeoShapeAssembly*>(fShape)) {
      // !!!! TGeoShapeAssembly makes a bad TBuffer3D
      return 0;
   }

   TEveGeoManagerHolder gmgr(fgGeoMangeur, fNSegments);

   TBuffer3D* buff  = fShape->MakeBuffer3D();
   TEveTrans& mx    = RefMainTrans();
   if (mx.GetUseTrans())
   {
      Int_t n = buff->NbPnts();
      Double_t* pnts = buff->fPnts;
      for(Int_t k = 0; k < n; ++k)
      {
         mx.MultiplyIP(&pnts[3*k]);
      }
   }
   return buff;
}

//==============================================================================
//==============================================================================
// TEveGeoShapeProjected
//==============================================================================

//______________________________________________________________________________
//
// A 3D projected TEveGeoShape.

ClassImp(TEveGeoShapeProjected);

//______________________________________________________________________________
TEveGeoShapeProjected::TEveGeoShapeProjected() :
   TEveElementList("TEveGeoShapeProjected", "", kTRUE),
   fBuff(0)
{
   // Constructor.
}

//______________________________________________________________________________
void TEveGeoShapeProjected::SetDepthLocal(Float_t /*d*/)
{
   // This should never be called as this class is only used for 3D
   // projections.
   // The implementation is required as this metod is abstract.
   // Just emits a warning if called.

   Warning("SetDepthLocal", "This function only exists to fulfill an abstract interface.");
}

//______________________________________________________________________________
void TEveGeoShapeProjected::SetProjection(TEveProjectionManager* mng,
                                          TEveProjectable* model)
{
   // This is virtual method from base-class TEveProjected.

   TEveProjected::SetProjection(mng, model);

   TEveGeoShape* gre = dynamic_cast<TEveGeoShape*>(fProjectable);
   SetMainColor(gre->GetMainColor());
   CopyVizParams(gre);
}

//______________________________________________________________________________
void TEveGeoShapeProjected::UpdateProjection()
{
   // This is virtual method from base-class TEveProjected.

   TEveGeoShape   *gre = dynamic_cast<TEveGeoShape*>(fProjectable);
   TEveProjection *prj = fManager->GetProjection();

   delete fBuff;
   fBuff = gre->MakeBuffer3D();

   if (fBuff)
   {
      fBuff->SetSectionsValid(TBuffer3D::kCore | TBuffer3D::kRawSizes | TBuffer3D::kRaw);

      Double_t *p = fBuff->fPnts;
      for (UInt_t i = 0; i < fBuff->NbPnts(); ++i, p+=3)
      {
         prj->ProjectPointdv(p, 0);
      }
   }

   ResetBBox();
}

//______________________________________________________________________________
void TEveGeoShapeProjected::ComputeBBox()
{
   // Override of virtual method from TAttBBox.

   if (fBuff && fBuff->NbPnts() > 0)
   {
      BBoxInit();

      Double_t *p = fBuff->fPnts;
      for (UInt_t i = 0; i < fBuff->NbPnts(); ++i, p+=3)
      {
         BBoxCheckPoint(p[0], p[1], p[2]);
      }
   }
   else
   {
      BBoxZero();
   }
}

//______________________________________________________________________________
void TEveGeoShapeProjected::Paint(Option_t* /*option*/)
{
   // Paint object.

   static const TEveException eh("TEveGeoShapeProjected::Paint ");

   if (fBuff == 0)
      return;

   TBuffer3D &buff = *fBuff;

   buff.fID           = this;
   buff.fColor        = GetMainColor();
   buff.fTransparency = GetMainTransparency();
   buff.fLocalFrame   = kTRUE;

   Int_t reqSec = gPad->GetViewer3D()->AddObject(buff);

   if (reqSec != TBuffer3D::kNone)
      Warning(eh, "Extra section required: reqSec=%d, shape=%s.", reqSec, GetName());
}
<|endoftext|>


<commit_before><commit_msg>device api test<commit_after>#include <vector>
#include <gtest/gtest.h>
#include <hip/hip_runtime.h>

#define HIP_CHECK(x) ASSERT_EQ(x, hipSuccess)

template <class T>
__global__
void axpy_kernel(const T *x, T *y, T a, size_t size)
{
    unsigned int i = blockIdx.x * blockDim.x + threadIdx.x;

    if(i < size)
    {
        y[i] += a * x[i];
    }
}

TEST(Tests, Saxpy)
{
    size_t N = 100;

    float a = 100.0f;
    std::vector<float> x(N, 2.0f);
    std::vector<float> y(N, 1.0f);

    float *d_x;
    float *d_y;
    HIP_CHECK(hipMalloc(&d_x, N*sizeof(float)));
    HIP_CHECK(hipMalloc(&d_y, N*sizeof(float)));
    HIP_CHECK(hipMemcpy(d_x, x.data(),
                        N*sizeof(float),
                        hipMemcpyHostToDevice));
    HIP_CHECK(hipMemcpy(d_y, y.data(),
                        N*sizeof(float),
                        hipMemcpyHostToDevice));
    HIP_CHECK(hipDeviceSynchronize());

    hipLaunchKernelGGL(HIP_KERNEL_NAME(axpy_kernel<float>),
                       dim3((N+255)/256), dim3(256), 0, 0,
                       d_x, d_y, a, N);
    HIP_CHECK(hipPeekAtLastError());

    HIP_CHECK(hipMemcpy(y.data(), d_y,
                        N*sizeof(float),
                        hipMemcpyDeviceToHost));
    HIP_CHECK(hipDeviceSynchronize());
    HIP_CHECK(hipFree(d_x));
    HIP_CHECK(hipFree(d_y));

    for(size_t i=0; i<N; ++i)
    {
        EXPECT_NEAR(y[i], 201.0f, 0.1f);
    }
}

TEST(Tests, Daxpy)
{
    size_t N = 100;

    double a = 100.0f;
    std::vector<double> x(N, 2.0f);
    std::vector<double> y(N, 1.0f);

    double *d_x;
    double *d_y;
    HIP_CHECK(hipMalloc(&d_x, N*sizeof(double)));
    HIP_CHECK(hipMalloc(&d_y, N*sizeof(double)));
    HIP_CHECK(hipMemcpy(d_x, x.data(),
                        N*sizeof(double),
                        hipMemcpyHostToDevice));
    HIP_CHECK(hipMemcpy(d_y, y.data(),
                        N*sizeof(double),
                        hipMemcpyHostToDevice));
    HIP_CHECK(hipDeviceSynchronize());

    hipLaunchKernelGGL(HIP_KERNEL_NAME(axpy_kernel<double>),
                       dim3((N+255)/256), dim3(256), 0, 0,
                       d_x, d_y, a, N);
    HIP_CHECK(hipPeekAtLastError());

    HIP_CHECK(hipMemcpy(y.data(), d_y,
                        N*sizeof(double),
                        hipMemcpyDeviceToHost));
    HIP_CHECK(hipDeviceSynchronize());
    HIP_CHECK(hipFree(d_x));
    HIP_CHECK(hipFree(d_y));

    for(size_t i=0; i<N; ++i)
    {
        EXPECT_NEAR(y[i], 201.0f, 0.1f);
    }
}
<|endoftext|>


<commit_before>#include "estimator/atmospheric_location_estimator.hpp"

#include "protocol/messages.hpp"

#include "unit_config.hpp"

// TODO: Initial location is not valid. Maybe we should be able to mark the
// estimate as invalid until a GPS fix is found?
AtmosphericLocationEstimator::AtmosphericLocationEstimator(Communicator& communicator)
  : loc{0.0, 0.0, 0.0}
    locationMessageStream(communicator, 5) {
}

LocationEstimate AtmosphericLocationEstimator::update(const SensorMeasurements& meas) {
  makeEstimate(meas);
  updateStream();

  return loc;
}

LocationEstimate AtmosphericLocationEstimator::makeEstimate(const SensorMeasurements& meas) {
  if(meas.gps) {
    loc.lat = (*meas.gps).lat;
    loc.lon = (*meas.gps).lon;
  }

  // TODO: Mix GPS and barometer readings to get an accuration altitude?
  // TODO: Pressure != altitude.
  if(meas.bar) {
    loc.alt = (*meas.bar).pressure;
  }

  return loc;
}

void AtmosphericLocationEstimator::updateStream() {
  if(locationMessageStream.ready()) {
    protocol::message::location_message_t m {
      .lat = loc.lat,
      .lon = loc.lon,
      .alt = loc.alt
    };

    locationMessageStream.publish(m);
  }
}
<commit_msg>Add missing comma.<commit_after>#include "estimator/atmospheric_location_estimator.hpp"

#include "protocol/messages.hpp"

#include "unit_config.hpp"

// TODO: Initial location is not valid. Maybe we should be able to mark the
// estimate as invalid until a GPS fix is found?
AtmosphericLocationEstimator::AtmosphericLocationEstimator(Communicator& communicator)
  : loc{0.0, 0.0, 0.0},
    locationMessageStream(communicator, 5) {
}

LocationEstimate AtmosphericLocationEstimator::update(const SensorMeasurements& meas) {
  makeEstimate(meas);
  updateStream();

  return loc;
}

LocationEstimate AtmosphericLocationEstimator::makeEstimate(const SensorMeasurements& meas) {
  if(meas.gps) {
    loc.lat = (*meas.gps).lat;
    loc.lon = (*meas.gps).lon;
  }

  // TODO: Mix GPS and barometer readings to get an accuration altitude?
  // TODO: Pressure != altitude.
  if(meas.bar) {
    loc.alt = (*meas.bar).pressure;
  }

  return loc;
}

void AtmosphericLocationEstimator::updateStream() {
  if(locationMessageStream.ready()) {
    protocol::message::location_message_t m {
      .lat = loc.lat,
      .lon = loc.lon,
      .alt = loc.alt
    };

    locationMessageStream.publish(m);
  }
}
<|endoftext|>