<commit_before>//
// Vehicles.cpp
//
// Copyright (c) 2001 Virtual Terrain Project
// Free for all uses, see license.txt for details.
//

#include "vtlib/vtlib.h"
#include "TerrainSceneWP.h"
#include "Engines.h"
#include "Hawaii.h"

///////////////////////////////
// helpers

void ConvertPurpleToColor(vtGroup *pModel, RGBf replace)
{
#if 0
	RGBf color;
	int i;

	vtGeom *pShape;
	vtMaterialArray *pApps;
	vtMaterial *pApp;

	// TODO
	// walk down through a part of the scene graph, converting
	// any geometry encountered
	if (pModel->m_pModel->IsClass(vtGeom))
	{
		pShape = (vtGeom *)pModel;
		bool has_purple = false;
		pApps = pShape->GetMaterials();
		if (!pApps)
			return;
		for (i = 0; i < pApps->GetSize(); i++)
		{
			pApp = pApps->GetAt(i);

			// is purple?
			color = pApp->GetDiffuse();
			if (color.r == 1.0f && color.g == 0.0f && color.b == 1.0f)
			{
				has_purple = true;
				break;
			}
		}
		if (has_purple)
		{
			vtMaterialArray *pApps2 = new vtMaterialArray();
			pApps2->CopyFrom(pApps);
			pShape->SetMaterials(pApps2);
			for (i = 0; i < pApps2->GetSize(); i++)
			{
				pApp = pApps2->GetAt(i);
				if (!pApp) continue;
				color = pApp->GetDiffuse();
				if (color.r == 1.0f && color.g == 0.0f && color.b == 1.0f)
				{
					vtMaterial *pApp2 = new vtMaterial();
					pApp2->Copy(pApp);
					pApps2->SetAt(i, pApp2);
					pApp2->SetDiffuse2(replace);
					pApp2->SetAmbient2(replace*0.6f);
				}
			}
		}
	}

	for (i = 0; i < pModel->GetNumChildren(); i++)
	{
		vtTransform *pChild = (vtTransform *) pModel->GetChild(i);
		ConvertPurpleToColor(pChild, replace);
	}
#endif
}

/////////////////////////////////////////

void IslandTerrain::create_road_vehicles()
{
	// must have roads for them to drive on
	if (!m_pRoadMap)
		return;
}

void PTerrain::create_ground_vehicles(float fSize, float fSpeed)
{
	FPoint3 vNormal, center;
	FPoint3 start_point;

	//add some cars!
	if (m_pRoadMap)
	{
		NodeGeom *n = (NodeGeom*) m_pRoadMap->GetFirstNode();
		vtTransform *car;
		int num, col;
		RGBf color;
		for (int i = 0; i < m_Params.m_iNumCars; i++)
		{
			if (n == NULL) {
				n = (NodeGeom*) m_pRoadMap->GetFirstNode();
			}
			num = i % 3;
			col = i % 5;

			switch (col) {
			case 0:
				color.Set(1.0f, 1.0f, 1.0f);
				break;
			case 1:
				color.Set(1.0f, 1.0f, 0.0f);
				break;
			case 2:
				color.Set(0.0f, 0.0f, .5f);
				break;
			case 3:
				color.Set(1.0f, 0.0f, 0.0f);
				break;
			case 4:
				color.Set(0.0f, .5f, 0.0f);
				break;
			}

			switch (num) {
			case 0:
				car = CreateVehicle("discovery", color, fSize);
				break;
			case 1:
				car = CreateVehicle("bronco", color, fSize);
				break;
			case 2:
				car = CreateVehicle("bus", color, fSize);
				break;
			}
			AddNode(car);
			PlantModelAtPoint(car, n->m_p);
//			AddCarEngine(car, 60.0f, n);
			n = (NodeGeom*) n->m_pNext;
		}
	}

/*	// try loading a car
	CarEngine *cEng;
	vtTransform *car;

	car = LoadModel("Vehicles/bronco_v2.DSM");
	float fAltitude;
	convert_meters_to_local_xz(192200, 2157700, start_point.x, start_point.z);
	m_pLocalGrid->FindAltitudeAtPoint(start_point, fAltitude, vNormal);

	if (car != NULL)
	{
		car->Size(.01f*sc,.01f*sc,.01f*sc);
		car->RotateLocal(YAXIS, PID2f); //adjust for MAX model
#if CAR_VIEW
		FollowerEngine* follower = new FollowerEngine(car, pScene->GetCamera());
		follower->SetName2("Follower Engine");
		AddEngine(follower, pScene);
#endif
		if (m_Params.m_bDoSound)
		{
			// sound
			vtSound3D* carnoise = new vtSound3D("Data/Vehicles/loud01.wav");
			carnoise->Initialize();
			carnoise->SetName2("Corvette Sound");
			carnoise->SetModel(1,1,30,30);	//set limit of how far away sound can be heard
			carnoise->SetTarget(car);		//set target
			carnoise->SetMute(true);		//mute the sound until later
			carnoise->Play(0, 0.0f);		//play the sound (muted)
			AddEngine(carnoise, pScene);
		}

		AddNode(car);

		if (m_pRoadMap != NULL) {
			//follow a road
			cEng = new CarEngine(start_point, m_pLocalGrid, 60.0f*fSize, .25f*fSize, m_pRoadMap->GetFirstNode(), 1, m_Params.m_fRoadHeight);
			cEng->SetName2("Car Engine");
//			cEng->GetPath("Data/test2.pf", m_pRoadMap);
		} else {
			//simple test: drive in a circle
			center = start_point;
			//for moving in a circle
			center.z -=4;
			cEng = new CarEngine(start_point, m_pLocalGrid, 60.0f*fSize, .25f*fSize, center);
			cEng->SetName2("Car Engine");
			//or drive in a straight line
			//cEng = new CarEngine(start_point, pLocalGrid, 60*fSize, .25*fSize);
		}

		cEng->SetTarget(car);
		if (cEng->SetTires()) {
			AddEngine(cEng, pScene);
		} else {
			//uh oh!
			delete cEng;
		}
	}
*/
}

VehicleType::VehicleType(const char *szName)
{
	m_strTypeName = szName;
	m_pNext = NULL;
	m_bAttemptedLoaded = false;
	m_iLods = 0;
}

//
// set filename and swap-out distance (in meters) for each LOD
//
void VehicleType::SetModelLod(int lod, const char *filename, float fDistance)
{
	if (lod > MAX_VEHICLE_LODS)
		return;
	m_strFilename[lod] = filename;
	if (m_iLods <= lod)
		m_iLods = lod+1;
	m_fDistance.SetAt(lod, fDistance * WORLD_SCALE);
}

void VehicleType::AttemptModelLoad()
{
	m_bAttemptedLoaded = true;
	if (m_iLods < 1)
		return;
#if 0
	// TODO
	for (int i = 0; i < m_iLods; i++)
	{
		if (vtModel *pMod = vtLoadModel(m_strFilename[i]))			// can read file?
			m_pModels.SetAt(i, pMod);
	}
#endif
}

Vehicle *VehicleType::CreateVehicle(RGBf &cColor, float fSize)
{
	// check if it's loaded yet
	if (!m_bAttemptedLoaded)
		AttemptModelLoad();
	if (m_pModels.GetSize() == 0)
		return NULL;

	Vehicle *pNewVehicle = new Vehicle();
	pNewVehicle->SetName2("VehicleLOD-" + m_strTypeName);

	float distances[10];
	// there is no distance at which the object should vanish for being too close
	distances[0] = 0.0f;

#if 0
	for (int i = 0; i < m_iLods; i++)
	{
		vtTransform *pNewModel = (Vehicle *)m_pModels.GetAt(i)->CreateClone();
		pNewVehicle->AddChild(pNewModel);
		distances[i+1] = m_fDistance.GetAt(i) * fSize;
	}
	pNewVehicle->SetRanges(distances, m_iLods+1);

	float scale = 0.01f * WORLD_SCALE;	// models are in cm
	pNewVehicle->m_fSize = fSize * scale;
	ConvertPurpleToColor(pNewVehicle, cColor);

	return pNewVehicle;
#else
	return NULL;
#endif
}

<commit_msg>removed big chunk of obsolete code<commit_after>//
// Vehicles.cpp
//
// Copyright (c) 2001 Virtual Terrain Project
// Free for all uses, see license.txt for details.
//

#include "vtlib/vtlib.h"
#include "TerrainSceneWP.h"
#include "Engines.h"
#include "Hawaii.h"

///////////////////////////////
// helpers

void ConvertPurpleToColor(vtGroup *pModel, RGBf replace)
{
#if 0
	RGBf color;
	int i;

	vtGeom *pShape;
	vtMaterialArray *pApps;
	vtMaterial *pApp;

	// TODO
	// walk down through a part of the scene graph, converting
	// any geometry encountered
	if (pModel->m_pModel->IsClass(vtGeom))
	{
		pShape = (vtGeom *)pModel;
		bool has_purple = false;
		pApps = pShape->GetMaterials();
		if (!pApps)
			return;
		for (i = 0; i < pApps->GetSize(); i++)
		{
			pApp = pApps->GetAt(i);

			// is purple?
			color = pApp->GetDiffuse();
			if (color.r == 1.0f && color.g == 0.0f && color.b == 1.0f)
			{
				has_purple = true;
				break;
			}
		}
		if (has_purple)
		{
			vtMaterialArray *pApps2 = new vtMaterialArray();
			pApps2->CopyFrom(pApps);
			pShape->SetMaterials(pApps2);
			for (i = 0; i < pApps2->GetSize(); i++)
			{
				pApp = pApps2->GetAt(i);
				if (!pApp) continue;
				color = pApp->GetDiffuse();
				if (color.r == 1.0f && color.g == 0.0f && color.b == 1.0f)
				{
					vtMaterial *pApp2 = new vtMaterial();
					pApp2->Copy(pApp);
					pApps2->SetAt(i, pApp2);
					pApp2->SetDiffuse2(replace);
					pApp2->SetAmbient2(replace*0.6f);
				}
			}
		}
	}

	for (i = 0; i < pModel->GetNumChildren(); i++)
	{
		vtTransform *pChild = (vtTransform *) pModel->GetChild(i);
		ConvertPurpleToColor(pChild, replace);
	}
#endif
}

/////////////////////////////////////////

void IslandTerrain::create_road_vehicles()
{
	// must have roads for them to drive on
	if (!m_pRoadMap)
		return;
}

void PTerrain::create_ground_vehicles(float fSize, float fSpeed)
{
	FPoint3 vNormal, center;
	FPoint3 start_point;

	//add some cars!
	if (m_pRoadMap)
	{
		NodeGeom *n = (NodeGeom*) m_pRoadMap->GetFirstNode();
		vtTransform *car;
		int num, col;
		RGBf color;
		for (int i = 0; i < m_Params.m_iNumCars; i++)
		{
			if (n == NULL) {
				n = (NodeGeom*) m_pRoadMap->GetFirstNode();
			}
			num = i % 3;
			col = i % 5;

			switch (col) {
			case 0:
				color.Set(1.0f, 1.0f, 1.0f);
				break;
			case 1:
				color.Set(1.0f, 1.0f, 0.0f);
				break;
			case 2:
				color.Set(0.0f, 0.0f, .5f);
				break;
			case 3:
				color.Set(1.0f, 0.0f, 0.0f);
				break;
			case 4:
				color.Set(0.0f, .5f, 0.0f);
				break;
			}

			switch (num) {
			case 0:
				car = CreateVehicle("discovery", color, fSize);
				break;
			case 1:
				car = CreateVehicle("bronco", color, fSize);
				break;
			case 2:
				car = CreateVehicle("bus", color, fSize);
				break;
			}
			AddNode(car);
			PlantModelAtPoint(car, n->m_p);
//			AddCarEngine(car, 60.0f, n);
			n = (NodeGeom*) n->m_pNext;
		}
	}
}

VehicleType::VehicleType(const char *szName)
{
	m_strTypeName = szName;
	m_pNext = NULL;
	m_bAttemptedLoaded = false;
	m_iLods = 0;
}

//
// set filename and swap-out distance (in meters) for each LOD
//
void VehicleType::SetModelLod(int lod, const char *filename, float fDistance)
{
	if (lod > MAX_VEHICLE_LODS)
		return;
	m_strFilename[lod] = filename;
	if (m_iLods <= lod)
		m_iLods = lod+1;
	m_fDistance.SetAt(lod, fDistance * WORLD_SCALE);
}

void VehicleType::AttemptModelLoad()
{
	m_bAttemptedLoaded = true;
	if (m_iLods < 1)
		return;
#if 0
	// TODO
	for (int i = 0; i < m_iLods; i++)
	{
		if (vtModel *pMod = vtLoadModel(m_strFilename[i]))			// can read file?
			m_pModels.SetAt(i, pMod);
	}
#endif
}

Vehicle *VehicleType::CreateVehicle(RGBf &cColor, float fSize)
{
	// check if it's loaded yet
	if (!m_bAttemptedLoaded)
		AttemptModelLoad();
	if (m_pModels.GetSize() == 0)
		return NULL;

	Vehicle *pNewVehicle = new Vehicle();
	pNewVehicle->SetName2("VehicleLOD-" + m_strTypeName);

	float distances[10];
	// there is no distance at which the object should vanish for being too close
	distances[0] = 0.0f;

#if 0
	for (int i = 0; i < m_iLods; i++)
	{
		vtTransform *pNewModel = (Vehicle *)m_pModels.GetAt(i)->CreateClone();
		pNewVehicle->AddChild(pNewModel);
		distances[i+1] = m_fDistance.GetAt(i) * fSize;
	}
	pNewVehicle->SetRanges(distances, m_iLods+1);

	float scale = 0.01f * WORLD_SCALE;	// models are in cm
	pNewVehicle->m_fSize = fSize * scale;
	ConvertPurpleToColor(pNewVehicle, cColor);

	return pNewVehicle;
#else
	return NULL;
#endif
}

<|endoftext|>


<commit_before>#include <UnitTest++/src/UnitTest++.h>
#include "rdestl/intrusive_slist.h"

namespace
{
	struct MyNode : public rde::intrusive_slist_node
	{
		explicit MyNode(int i = 0): data(i) {}
		int	data;
	};

	TEST(DefaultCtorConstructsEmptyList)
	{
		rde::intrusive_slist<MyNode> l;
		CHECK(l.empty());
		CHECK_EQUAL(0ul, l.size());
	}
	TEST(PushFront)
	{
		rde::intrusive_slist<MyNode> l;
		MyNode node;
		node.data = 5;
		l.push_front(&node);
		CHECK_EQUAL(1ul, l.size());
		MyNode node2;
		node2.data = 10;
		l.push_front(&node2);
		CHECK_EQUAL(2ul, l.size());
		CHECK_EQUAL(10, l.front()->data);
	}
	TEST(PopFront)
	{
		rde::intrusive_slist<MyNode> l;
		MyNode node;
		node.data = 5;
		l.push_front(&node);
		MyNode node2;
		node2.data = 10;
		l.push_front(&node2);
		MyNode node3;
		node3.data = 15;
		l.push_front(&node3);
		CHECK_EQUAL(3ul, l.size());
		l.pop_front();
		CHECK_EQUAL(2ul, l.size());
		CHECK_EQUAL(10, l.front()->data);
		l.pop_front();
		CHECK_EQUAL(1ul, l.size());
		CHECK_EQUAL(5, l.front()->data);
		l.pop_front();
		CHECK(l.empty());
		CHECK_EQUAL(0ul, l.size());
	}
	TEST(Previous)
	{
		rde::intrusive_slist<MyNode> l;
		MyNode node;
		node.data = 5;
		l.push_front(&node);
		MyNode node2;
		node2.data = 10;
		l.push_front(&node2);
		rde::intrusive_slist<MyNode>::iterator it = l.begin();
		++it;
		rde::intrusive_slist<MyNode>::iterator itPrev = l.previous(it);
		CHECK(itPrev == l.begin());
	}
	TEST(Clear)
	{
		rde::intrusive_slist<MyNode> l;
		l.push_front(new MyNode(5));
		l.push_front(new MyNode(6));
		l.push_front(new MyNode(7));
		l.push_front(new MyNode(8));
		CHECK_EQUAL(4ul, l.size());
		l.clear();
		CHECK(l.empty());
		CHECK_EQUAL(0ul, l.size());
	}
	TEST(GetIterator)
	{
		rde::intrusive_slist<MyNode> l;
		l.push_front(new MyNode(5));
		l.push_front(new MyNode(6));
		MyNode* n(new MyNode(7));
		l.push_front(n);
		l.push_front(new MyNode(8));
		rde::intrusive_slist<MyNode>::iterator it = l.get_iterator(n);
		CHECK_EQUAL(7, it->data);
	}
}

<commit_msg>Bugfixes - memory leaks<commit_after>#include <UnitTest++/src/UnitTest++.h>
#include "rdestl/intrusive_slist.h"

namespace
{
	struct MyNode : public rde::intrusive_slist_node
	{
		explicit MyNode(int i = 0): data(i) {}
		int	data;
	};

	TEST(DefaultCtorConstructsEmptyList)
	{
		rde::intrusive_slist<MyNode> l;
		CHECK(l.empty());
		CHECK_EQUAL(0ul, l.size());
	}
	TEST(PushFront)
	{
		rde::intrusive_slist<MyNode> l;
		MyNode node;
		node.data = 5;
		l.push_front(&node);
		CHECK_EQUAL(1ul, l.size());
		MyNode node2;
		node2.data = 10;
		l.push_front(&node2);
		CHECK_EQUAL(2ul, l.size());
		CHECK_EQUAL(10, l.front()->data);
	}
	TEST(PopFront)
	{
		rde::intrusive_slist<MyNode> l;
		MyNode node;
		node.data = 5;
		l.push_front(&node);
		MyNode node2;
		node2.data = 10;
		l.push_front(&node2);
		MyNode node3;
		node3.data = 15;
		l.push_front(&node3);
		CHECK_EQUAL(3ul, l.size());
		l.pop_front();
		CHECK_EQUAL(2ul, l.size());
		CHECK_EQUAL(10, l.front()->data);
		l.pop_front();
		CHECK_EQUAL(1ul, l.size());
		CHECK_EQUAL(5, l.front()->data);
		l.pop_front();
		CHECK(l.empty());
		CHECK_EQUAL(0ul, l.size());
	}
	TEST(Previous)
	{
		rde::intrusive_slist<MyNode> l;
		MyNode node;
		node.data = 5;
		l.push_front(&node);
		MyNode node2;
		node2.data = 10;
		l.push_front(&node2);
		rde::intrusive_slist<MyNode>::iterator it = l.begin();
		++it;
		rde::intrusive_slist<MyNode>::iterator itPrev = l.previous(it);
		CHECK(itPrev == l.begin());
	}
	TEST(Clear)
	{
		rde::intrusive_slist<MyNode> l;
		MyNode n0(5); l.push_front(&n0);
		MyNode n1(6); l.push_front(&n1);
		MyNode n2(7); l.push_front(&n2);
		MyNode n3(8); l.push_front(&n3);
		CHECK_EQUAL(4ul, l.size());
		l.clear();
		CHECK(l.empty());
		CHECK_EQUAL(0ul, l.size());
	}
	TEST(GetIterator)
	{
		rde::intrusive_slist<MyNode> l;
		MyNode n0(5); l.push_front(&n0);
		MyNode n1(6); l.push_front(&n1);
		MyNode* n(new MyNode(7));
		l.push_front(n);
		MyNode n2(8); l.push_front(&n2);
		rde::intrusive_slist<MyNode>::iterator it = l.get_iterator(n);
		CHECK_EQUAL(7, it->data);
		delete n;
	}
}

<|endoftext|>


<commit_before>#include "eventgenerator.h"
#include "parse.h"
#include "eventgeneratorfactory.h"
#include <thread.h>
#include <vector>
using namespace std;

EventGenerator*
EventGenerator::parse(char *filename)
{
  ifstream in(filename);
  if(!in) {
    cerr << "no such file " << filename << endl;
    threadexitsall(0);
  }

  string line;
  EventGenerator *gen = 0;
  while(getline(in,line)) {
    vector<string> words = split(line);

    // skip empty lines and commented lines
    if(words.empty() || words[0][0] == '#')
      continue;

    // read generator string
    if(words[0] != "generator") {
      cerr << "first line in event file should be ``generator [G]''" << endl;
      exit(-1);
    }
    words.erase(words.begin());

    string generator = words[0];
    words.erase(words.begin());
    gen = EventGeneratorFactory::Instance()->create(generator, &words);
    break;
  }

  if(!gen) {
    cerr << "the generator you specified is unknown" << endl;
    exit(-1);
  }

  // leave the rest of the file to the specific generator
  gen->parse(in);

  return gen;
}
<commit_msg>fix strib's compiler error<commit_after>#include "eventgenerator.h"
#include "parse.h"
#include "eventgeneratorfactory.h"
#include <lib9.h>
#include <thread.h>
#include <vector>
using namespace std;

EventGenerator*
EventGenerator::parse(char *filename)
{
  ifstream in(filename);
  if(!in) {
    cerr << "no such file " << filename << endl;
    threadexitsall(0);
  }

  string line;
  EventGenerator *gen = 0;
  while(getline(in,line)) {
    vector<string> words = split(line);

    // skip empty lines and commented lines
    if(words.empty() || words[0][0] == '#')
      continue;

    // read generator string
    if(words[0] != "generator") {
      cerr << "first line in event file should be ``generator [G]''" << endl;
      exit(-1);
    }
    words.erase(words.begin());

    string generator = words[0];
    words.erase(words.begin());
    gen = EventGeneratorFactory::Instance()->create(generator, &words);
    break;
  }

  if(!gen) {
    cerr << "the generator you specified is unknown" << endl;
    exit(-1);
  }

  // leave the rest of the file to the specific generator
  gen->parse(in);

  return gen;
}
<|endoftext|>


<commit_before>#include "FanDefinition.h"
#include "ui/UIWebView.h"
#include "../compiler.h"
#include "../TilesImage.h"
#include "../mahjong-algorithm/stringify.h"
#include "../mahjong-algorithm/fan_calculator.h"
#include "../widget/LoadingView.h"

#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS) && !defined(CC_PLATFORM_OS_TVOS)
#define HAS_WEBVIEW 1
#else
#define HAS_WEBVIEW 0
#endif

USING_NS_CC;

static std::vector<std::string> g_principles;
static std::vector<std::string> g_definitions;

static void replaceTilesToImage(std::string &text, float scale) {
    char tilesStr[128];
    mahjong::tile_t tiles[14];
    long tilesCnt;
    char imgStr[1024];

    std::string::size_type pos = text.find('[');
    while (pos != std::string::npos) {
        const char *str = text.c_str();
        int readLen;
        if (sscanf(str + pos + 1, "%[^]]%n", tilesStr, &readLen) != EOF
            && str[pos + readLen + 1] == ']'
            && (tilesCnt = mahjong::parse_tiles(tilesStr, tiles, 14)) >= 0) {
            size_t totalWriteLen = 0;
            for (long i = 0; i < tilesCnt; ++i) {
                int writeLen = snprintf(imgStr + totalWriteLen, sizeof(imgStr) - totalWriteLen,
                    "",
                    tilesImageName[tiles[i]], (int)(TILE_WIDTH * scale), (int)(TILE_HEIGHT * scale));
                totalWriteLen += writeLen;
            }
            text.replace(pos, readLen + 2, imgStr);
            pos = text.find('[', pos + totalWriteLen);
        }
        else {
            pos = text.find('[', pos + 1);
        }
    }
}

Scene *FanDefinitionScene::create(size_t idx) {
    auto scene = new (std::nothrow) FanDefinitionScene();
    scene->initWithIndex(idx);
    scene->autorelease();
    return scene;
}

bool FanDefinitionScene::initWithIndex(size_t idx) {
    const char *title = idx < 100 ? mahjong::fan_name[idx] : principle_title[idx - 100];
    if (UNLIKELY(!BaseScene::initWithTitle(title))) {
        return false;
    }

    if (LIKELY(!g_definitions.empty() && !g_principles.empty())) {
        createContentView(idx);
        return true;
    }

    Size visibleSize = Director::getInstance()->getVisibleSize();
    Vec2 origin = Director::getInstance()->getVisibleOrigin();

    LoadingView *loadingView = LoadingView::create();
    this->addChild(loadingView);
    loadingView->setPosition(origin);

#if HAS_WEBVIEW
    float scale = 1.0f;
    float maxWidth = (visibleSize.width - 10) / 18;
    if (maxWidth < 25) {
        scale = maxWidth / TILE_WIDTH;
    }
#else
    float scale = 1.0f / Director::getInstance()->getContentScaleFactor();
#endif

    auto thiz = makeRef(this);  // 保证线程回来之前不析构
    std::thread([thiz, idx, scale, loadingView]() {
        // 读文件
        if (g_definitions.empty()) {
            ValueVector valueVec = FileUtils::getInstance()->getValueVectorFromFile("text/score_definition.xml");
            g_definitions.reserve(valueVec.size());
            std::transform(valueVec.begin(), valueVec.end(), std::back_inserter(g_definitions), [scale](const Value &value) {
                std::string ret = value.asString();
                replaceTilesToImage(ret, scale);
                return std::move(ret);
            });
        }

        if (g_principles.empty()) {
            ValueVector valueVec = FileUtils::getInstance()->getValueVectorFromFile("text/score_principles.xml");
            g_principles.reserve(valueVec.size());
            std::transform(valueVec.begin(), valueVec.end(), std::back_inserter(g_principles), [scale](const Value &value) {
                std::string ret = value.asString();
                replaceTilesToImage(ret, scale);
                return std::move(ret);
            });
        }

        // 切换到cocos线程
        Director::getInstance()->getScheduler()->performFunctionInCocosThread([thiz, idx, loadingView]() {
            if (LIKELY(thiz->isRunning())) {
                loadingView->removeFromParent();
                thiz->createContentView(idx);
            }
        });
    }).detach();

    return true;
}

void FanDefinitionScene::createContentView(size_t idx) {
    Size visibleSize = Director::getInstance()->getVisibleSize();
    Vec2 origin = Director::getInstance()->getVisibleOrigin();

    const std::string &text = idx < 100 ? g_definitions[idx] : g_principles[idx - 100];

#if HAS_WEBVIEW
    experimental::ui::WebView *webView = experimental::ui::WebView::create();
    webView->setContentSize(Size(visibleSize.width, visibleSize.height - 35));
    webView->setOnEnterCallback(std::bind(&experimental::ui::WebView::loadHTMLString, webView, std::ref(text), ""));
    this->addChild(webView);
    webView->setPosition(Vec2(origin.x + visibleSize.width * 0.5f, origin.y + visibleSize.height * 0.5f - 15.0f));
#else
    ui::RichText *richText = ui::RichText::createWithXML("" + text + "");
    richText->setContentSize(Size(visibleSize.width - 10, 0));
    richText->ignoreContentAdaptWithSize(false);
    richText->setVerticalSpace(2);
    richText->formatText();
    this->addChild(richText);
    richText->setPosition(Vec2(origin.x + visibleSize.width * 0.5f, origin.y + visibleSize.height - 40.0f));
#endif
}
<commit_msg>可能潜在线程问题<commit_after>#include "FanDefinition.h"
#include "ui/UIWebView.h"
#include "../compiler.h"
#include "../TilesImage.h"
#include "../mahjong-algorithm/stringify.h"
#include "../mahjong-algorithm/fan_calculator.h"
#include "../widget/LoadingView.h"

#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS) && !defined(CC_PLATFORM_OS_TVOS)
#define HAS_WEBVIEW 1
#else
#define HAS_WEBVIEW 0
#endif

USING_NS_CC;

static std::vector<std::string> g_principles;
static std::vector<std::string> g_definitions;

static void replaceTilesToImage(std::string &text, float scale) {
    char tilesStr[128];
    mahjong::tile_t tiles[14];
    long tilesCnt;
    char imgStr[1024];

    std::string::size_type pos = text.find('[');
    while (pos != std::string::npos) {
        const char *str = text.c_str();
        int readLen;
        if (sscanf(str + pos + 1, "%[^]]%n", tilesStr, &readLen) != EOF
            && str[pos + readLen + 1] == ']'
            && (tilesCnt = mahjong::parse_tiles(tilesStr, tiles, 14)) >= 0) {
            size_t totalWriteLen = 0;
            for (long i = 0; i < tilesCnt; ++i) {
                int writeLen = snprintf(imgStr + totalWriteLen, sizeof(imgStr) - totalWriteLen,
                    "",
                    tilesImageName[tiles[i]], (int)(TILE_WIDTH * scale), (int)(TILE_HEIGHT * scale));
                totalWriteLen += writeLen;
            }
            text.replace(pos, readLen + 2, imgStr);
            pos = text.find('[', pos + totalWriteLen);
        }
        else {
            pos = text.find('[', pos + 1);
        }
    }
}

Scene *FanDefinitionScene::create(size_t idx) {
    auto scene = new (std::nothrow) FanDefinitionScene();
    scene->initWithIndex(idx);
    scene->autorelease();
    return scene;
}

bool FanDefinitionScene::initWithIndex(size_t idx) {
    const char *title = idx < 100 ? mahjong::fan_name[idx] : principle_title[idx - 100];
    if (UNLIKELY(!BaseScene::initWithTitle(title))) {
        return false;
    }

    if (LIKELY(g_definitions.size() == 82 && g_principles.size() == 5)) {
        createContentView(idx);
        return true;
    }

    Size visibleSize = Director::getInstance()->getVisibleSize();
    Vec2 origin = Director::getInstance()->getVisibleOrigin();

    LoadingView *loadingView = LoadingView::create();
    this->addChild(loadingView);
    loadingView->setPosition(origin);

#if HAS_WEBVIEW
    float scale = 1.0f;
    float maxWidth = (visibleSize.width - 10) / 18;
    if (maxWidth < 25) {
        scale = maxWidth / TILE_WIDTH;
    }
#else
    float scale = 1.0f / Director::getInstance()->getContentScaleFactor();
#endif

    auto thiz = makeRef(this);  // 保证线程回来之前不析构
    std::thread([thiz, idx, scale, loadingView]() {
        // 读文件
        std::vector<std::string> definitions;
        ValueVector valueVec = FileUtils::getInstance()->getValueVectorFromFile("text/score_definition.xml");
        if (valueVec.size() == 82) {
            definitions.reserve(82);
            std::transform(valueVec.begin(), valueVec.end(), std::back_inserter(definitions), [scale](const Value &value) {
                std::string ret = value.asString();
                replaceTilesToImage(ret, scale);
                return std::move(ret);
            });
        }

        std::vector<std::string> principles;
        valueVec = FileUtils::getInstance()->getValueVectorFromFile("text/score_principles.xml");
        if (valueVec.size() == 5) {
            principles.reserve(5);
            std::transform(valueVec.begin(), valueVec.end(), std::back_inserter(principles), [scale](const Value &value) {
                std::string ret = value.asString();
                replaceTilesToImage(ret, scale);
                return std::move(ret);
            });
        }

        // 切换到cocos线程
        Director::getInstance()->getScheduler()->performFunctionInCocosThread([thiz, idx, loadingView, definitions, principles]() mutable {
            g_definitions.swap(definitions);
            g_principles.swap(principles);

            if (LIKELY(thiz->isRunning())) {
                loadingView->removeFromParent();
                thiz->createContentView(idx);
            }
        });
    }).detach();

    return true;
}

void FanDefinitionScene::createContentView(size_t idx) {
    Size visibleSize = Director::getInstance()->getVisibleSize();
    Vec2 origin = Director::getInstance()->getVisibleOrigin();

    const std::string &text = idx < 100 ? g_definitions[idx] : g_principles[idx - 100];

#if HAS_WEBVIEW
    experimental::ui::WebView *webView = experimental::ui::WebView::create();
    webView->setContentSize(Size(visibleSize.width, visibleSize.height - 35));
    webView->setOnEnterCallback(std::bind(&experimental::ui::WebView::loadHTMLString, webView, std::ref(text), ""));
    this->addChild(webView);
    webView->setPosition(Vec2(origin.x + visibleSize.width * 0.5f, origin.y + visibleSize.height * 0.5f - 15.0f));
#else
    ui::RichText *richText = ui::RichText::createWithXML("" + text + "");
    richText->setContentSize(Size(visibleSize.width - 10, 0));
    richText->ignoreContentAdaptWithSize(false);
    richText->setVerticalSpace(2);
    richText->formatText();
    this->addChild(richText);
    richText->setPosition(Vec2(origin.x + visibleSize.width * 0.5f, origin.y + visibleSize.height - 40.0f));
#endif
}
<|endoftext|>


<commit_before>/*
 * Software License Agreement (BSD License)
 *
 *  Point Cloud Library (PCL) - www.pointclouds.org
 *  Copyright (c) 2010-2011, Willow Garage, Inc.
 *
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 * $Id: organized.hpp 3220 2011-11-21 15:50:53Z koenbuys $
 *
 */

#ifndef PCL_SEARCH_IMPL_FLANN_SEARCH_H_
#define PCL_SEARCH_IMPL_FLANN_SEARCH_H_

#include "pcl/search/flann_search.h"
#include <flann/flann.hpp>

//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT>
typename pcl::search::FlannSearch<PointT>::IndexPtr
pcl::search::FlannSearch<PointT>::KdTreeIndexCreator::createIndex (const flann::Matrix<float> &data)
{
  return (IndexPtr (new flann::KDTreeSingleIndex<flann::L2<float> > (data,flann::KDTreeSingleIndexParams (15))));
}

//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT>
pcl::search::FlannSearch<PointT>::FlannSearch(FlannIndexCreator *creator)
  :creator_ (creator), eps_ (0), input_copied_for_flann_ (false)
{
  point_representation_.reset (new DefaultPointRepresentation<PointT>);
  dim_ = point_representation_->getNumberOfDimensions ();
}

//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT>
pcl::search::FlannSearch<PointT>::~FlannSearch()
{
  delete creator_;
  if (input_copied_for_flann_)
    delete [] input_flann_.ptr();
}

//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> void
pcl::search::FlannSearch<PointT>::setInputCloud (const PointCloudConstPtr& cloud, const IndicesConstPtr& indices)
{
  input_ = cloud;
  indices_ = indices;
  convertInputToFlannMatrix ();
  index_ = creator_->createIndex (input_flann_);
  index_->buildIndex ();
}

//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> int
pcl::search::FlannSearch<PointT>::nearestKSearch (const PointT &point, int k, std::vector<int> &indices, std::vector<float> &dists)
{
  bool can_cast = point_representation_->isTrivial ();

  float* data = 0;
  if (!can_cast)
  {
    data = new float [point_representation_->getNumberOfDimensions ()];
    point_representation_->vectorize (point,data);
  }

  float* cdata = can_cast ? const_cast<float*> (reinterpret_cast<const float*> (&point)): data;
  const flann::Matrix<float> m (cdata ,1, point_representation_->getNumberOfDimensions ());

  flann::SearchParams p;
  p.eps = eps_;
  indices.resize (k,-1);
  dists.resize (k);
  flann::Matrix<int> i (&indices[0],1,k);
  flann::Matrix<float> d (&dists[0],1,k);
  int result = index_->knnSearch (m,i,d,k, p);

  delete [] data;

  if (!identity_mapping_)
  {
    for (size_t i = 0; i < (size_t)k; ++i)
    {
      int& neighbor_index = indices[i];
      neighbor_index = index_mapping_[neighbor_index];
    }
  }
  return result;
}

//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> void
pcl::search::FlannSearch<PointT>::nearestKSearch (const PointCloud& cloud, const std::vector<int>& indices, int k, std::vector< std::vector<int> >& k_indices,
        std::vector< std::vector<float> >& k_sqr_distances)
{
  if (indices.empty ())
  {
    k_indices.resize (cloud.size ());
    k_sqr_distances.resize (cloud.size ());

    bool can_cast = point_representation_->isTrivial ();

    // full point cloud + trivial copy operation = no need to do any conversion/copying to the flann matrix!
    float* data=0;
    if (!can_cast)
    {
      data = new float[dim_*cloud.size ()];
      for (size_t i = 0; i < cloud.size (); ++i)
      {
        float* out = data+i*dim_;
        point_representation_->vectorize (cloud[i],out);
      }
    }

    // const cast is evil, but the matrix constructor won't change the data, and the
    // search won't change the matrix
    float* cdata = can_cast ? const_cast<float*> (reinterpret_cast<const float*> (&cloud[0])): data;
    const flann::Matrix<float> m (cdata ,cloud.size (), dim_, can_cast ? sizeof(PointT)/sizeof(float) : dim_ );

    flann::SearchParams p;
    p.eps = eps_;
    index_->knnSearch (m,k_indices,k_sqr_distances,k, p);

    delete [] data;
  }
  else // if indices are present, the cloud has to be copied anyway. Only copy the relevant parts of the points here.
  {
    k_indices.resize (indices.size ());
    k_sqr_distances.resize (indices.size ());

    float* data=new float [dim_*indices.size ()];
    for (size_t i = 0; i < indices.size (); ++i)
    {
      float* out = data+i*dim_;
      point_representation_->vectorize (cloud[indices[i]],out);
    }
    const flann::Matrix<float> m (data ,indices.size (), point_representation_->getNumberOfDimensions ());

    flann::SearchParams p;
    p.eps = eps_;
    index_->knnSearch (m,k_indices,k_sqr_distances,k, p);

    delete[] data;
  }
  if (!identity_mapping_)
  {
    for (size_t j = 0; j < k_indices.size (); ++j)
    {
      for (size_t i = 0; i < (size_t)k; ++i)
      {
        int& neighbor_index = k_indices[j][i];
        neighbor_index = index_mapping_[neighbor_index];
      }
    }
  }
}

//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> int
pcl::search::FlannSearch<PointT>::radiusSearch (const PointT& point, double radius,
    std::vector<int> &indices, std::vector<float> &distances,
    int max_nn) const
{
  bool can_cast = point_representation_->isTrivial ();

  float* data = 0;
  if (!can_cast)
  {
    data = new float [point_representation_->getNumberOfDimensions ()];
    point_representation_->vectorize (point,data);
  }

  float* cdata = can_cast ? const_cast<float*> (reinterpret_cast<const float*> (&point)) : data;
  const flann::Matrix<float> m (cdata ,1, point_representation_->getNumberOfDimensions ());

  flann::SearchParams p;
  p.eps = eps_;
  p.max_neighbors = max_nn;
  std::vector<std::vector<int> > i (1);
  std::vector<std::vector<float> > d (1);
  int result = index_->radiusSearch (m,i,d,radius*radius, p);

  delete [] data;
  indices=i [0];
  distances=d [0];

  if (!identity_mapping_)
  {
    for (size_t i = 0; i < indices.size (); ++i)
    {
      int& neighbor_index = indices [i];
      neighbor_index = index_mapping_ [neighbor_index];
    }
  }
  return result;
}

//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> void
pcl::search::FlannSearch<PointT>::radiusSearch (
    const PointCloud& cloud, const std::vector<int>& indices, double radius, std::vector< std::vector<int> >& k_indices,
    std::vector< std::vector<float> >& k_sqr_distances, int max_nn)
{
  if (indices.empty ()) // full point cloud + trivial copy operation = no need to do any conversion/copying to the flann matrix!
  {
    k_indices.resize (cloud.size ());
    k_sqr_distances.resize (cloud.size ());

    bool can_cast = point_representation_->isTrivial ();

    float* data = 0;
    if (!can_cast)
    {
      data = new float[dim_*cloud.size ()];
      for (size_t i = 0; i < cloud.size (); ++i)
      {
        float* out = data+i*dim_;
        point_representation_->vectorize (cloud[i],out);
      }
    }

    float* cdata = can_cast ? const_cast<float*> (reinterpret_cast<const float*> (&cloud[0])) : data;
    const flann::Matrix<float> m (cdata ,cloud.size (), dim_, can_cast ? sizeof(PointT)/sizeof(float) : dim_ );

    flann::SearchParams p;
    p.eps = eps_;
    p.max_neighbors = max_nn;
    index_->radiusSearch (m,k_indices,k_sqr_distances,radius*radius, p);

    delete [] data;
  }
  else // if indices are present, the cloud has to be copied anyway. Only copy the relevant parts of the points here.
  {
    k_indices.resize (indices.size ());
    k_sqr_distances.resize (indices.size ());

    float* data = new float [dim_ * indices.size ()];
    for (size_t i = 0; i < indices.size (); ++i)
    {
      float* out = data+i*dim_;
      point_representation_->vectorize (cloud[indices[i]], out);
    }
    const flann::Matrix<float> m (data, cloud.size (), point_representation_->getNumberOfDimensions ());

    flann::SearchParams p;
    p.eps = eps_;
    p.max_neighbors = max_nn;
    index_->radiusSearch (m, k_indices, k_sqr_distances, radius * radius, p);

    delete[] data;
  }
  if (!identity_mapping_)
  {
    for (size_t j = 0; j < k_indices.size (); ++j )
    {
      for (size_t i = 0; i < k_indices[j].size (); ++i)
      {
        int& neighbor_index = k_indices[j][i];
        neighbor_index = index_mapping_[neighbor_index];
      }
    }
  }
}

//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> void
pcl::search::FlannSearch<PointT>::convertInputToFlannMatrix ()
{
  int original_no_of_points = indices_ && !indices_->empty () ? indices_->size () : input_->size ();

  if (input_copied_for_flann_)
    delete input_flann_.ptr();
  input_copied_for_flann_ = true;
  identity_mapping_ = true;

  input_flann_ = flann::Matrix<float> (new float[original_no_of_points*point_representation_->getNumberOfDimensions ()], original_no_of_points, point_representation_->getNumberOfDimensions ());

  //cloud_ = (float*)malloc (original_no_of_points * dim_ * sizeof (float));
  float* cloud_ptr = input_flann_.ptr();
  //index_mapping_.reserve(original_no_of_points);
  //identity_mapping_ = true;

  if (!indices_ || indices_->empty ())
  {
    /// TODO: implement "no NaN check" option that just re-uses the cloud data in the flann matrix
    for (int i = 0; i < original_no_of_points; ++i)
    {
      const PointT& point = (*input_)[i];
      // Check if the point is invalid
      if (!point_representation_->isValid (point))
      {
        identity_mapping_ = false;
        continue;
      }

      index_mapping_.push_back (i);  // If the returned index should be for the indices vector

      point_representation_->vectorize (point, cloud_ptr);
      cloud_ptr += dim_;
    }

  }
  else
  {
    for (int indices_index = 0; indices_index < original_no_of_points; ++indices_index)
    {
      int cloud_index = (*indices_)[indices_index];
      const PointT&  point = (*input_)[cloud_index];
      // Check if the point is invalid
      if (!point_representation_->isValid (point))
      {
        identity_mapping_ = false;
        continue;
      }

      index_mapping_.push_back (indices_index);  // If the returned index should be for the indices vector

      point_representation_->vectorize (point, cloud_ptr);
      cloud_ptr += dim_;
    }
  }
  input_flann_.rows = index_mapping_.size ();
}

#define PCL_INSTANTIATE_FlannSearch(T) template class PCL_EXPORTS pcl::search::FlannSearch<T>;

#endif
<commit_msg> * FlannSearch: adapted use of flann::Matrix to new semantics of the 'stride' parameter, fixing incorrect results and a crash<commit_after>/*
 * Software License Agreement (BSD License)
 *
 *  Point Cloud Library (PCL) - www.pointclouds.org
 *  Copyright (c) 2010-2011, Willow Garage, Inc.
 *
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 * $Id: organized.hpp 3220 2011-11-21 15:50:53Z koenbuys $
 *
 */

#ifndef PCL_SEARCH_IMPL_FLANN_SEARCH_H_
#define PCL_SEARCH_IMPL_FLANN_SEARCH_H_

#include "pcl/search/flann_search.h"
#include <flann/flann.hpp>

//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT>
typename pcl::search::FlannSearch<PointT>::IndexPtr
pcl::search::FlannSearch<PointT>::KdTreeIndexCreator::createIndex (const flann::Matrix<float> &data)
{
  return (IndexPtr (new flann::KDTreeSingleIndex<flann::L2<float> > (data,flann::KDTreeSingleIndexParams (15))));
}

//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT>
pcl::search::FlannSearch<PointT>::FlannSearch(FlannIndexCreator *creator)
  :creator_ (creator), eps_ (0), input_copied_for_flann_ (false)
{
  point_representation_.reset (new DefaultPointRepresentation<PointT>);
  dim_ = point_representation_->getNumberOfDimensions ();
}

//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT>
pcl::search::FlannSearch<PointT>::~FlannSearch()
{
  delete creator_;
  if (input_copied_for_flann_)
    delete [] input_flann_.ptr();
}

//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> void
pcl::search::FlannSearch<PointT>::setInputCloud (const PointCloudConstPtr& cloud, const IndicesConstPtr& indices)
{
  input_ = cloud;
  indices_ = indices;
  convertInputToFlannMatrix ();
  index_ = creator_->createIndex (input_flann_);
  index_->buildIndex ();
}

//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> int
pcl::search::FlannSearch<PointT>::nearestKSearch (const PointT &point, int k, std::vector<int> &indices, std::vector<float> &dists)
{
  bool can_cast = point_representation_->isTrivial ();

  float* data = 0;
  if (!can_cast)
  {
    data = new float [point_representation_->getNumberOfDimensions ()];
    point_representation_->vectorize (point,data);
  }

  float* cdata = can_cast ? const_cast<float*> (reinterpret_cast<const float*> (&point)): data;
  const flann::Matrix<float> m (cdata ,1, point_representation_->getNumberOfDimensions ());

  flann::SearchParams p;
  p.eps = eps_;
  indices.resize (k,-1);
  dists.resize (k);
  flann::Matrix<int> i (&indices[0],1,k);
  flann::Matrix<float> d (&dists[0],1,k);
  int result = index_->knnSearch (m,i,d,k, p);

  delete [] data;

  if (!identity_mapping_)
  {
    for (size_t i = 0; i < (size_t)k; ++i)
    {
      int& neighbor_index = indices[i];
      neighbor_index = index_mapping_[neighbor_index];
    }
  }
  return result;
}

//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> void
pcl::search::FlannSearch<PointT>::nearestKSearch (const PointCloud& cloud, const std::vector<int>& indices, int k, std::vector< std::vector<int> >& k_indices,
        std::vector< std::vector<float> >& k_sqr_distances)
{
  if (indices.empty ())
  {
    k_indices.resize (cloud.size ());
    k_sqr_distances.resize (cloud.size ());

    bool can_cast = point_representation_->isTrivial ();

    // full point cloud + trivial copy operation = no need to do any conversion/copying to the flann matrix!
    float* data=0;
    if (!can_cast)
    {
      data = new float[dim_*cloud.size ()];
      for (size_t i = 0; i < cloud.size (); ++i)
      {
        float* out = data+i*dim_;
        point_representation_->vectorize (cloud[i],out);
      }
    }

    // const cast is evil, but the matrix constructor won't change the data, and the
    // search won't change the matrix
    float* cdata = can_cast ? const_cast<float*> (reinterpret_cast<const float*> (&cloud[0])): data;
    const flann::Matrix<float> m (cdata ,cloud.size (), dim_, can_cast ? sizeof (PointT) : dim_ * sizeof (float) );

    flann::SearchParams p;
    p.eps = eps_;
    index_->knnSearch (m,k_indices,k_sqr_distances,k, p);

    delete [] data;
  }
  else // if indices are present, the cloud has to be copied anyway. Only copy the relevant parts of the points here.
  {
    k_indices.resize (indices.size ());
    k_sqr_distances.resize (indices.size ());

    float* data=new float [dim_*indices.size ()];
    for (size_t i = 0; i < indices.size (); ++i)
    {
      float* out = data+i*dim_;
      point_representation_->vectorize (cloud[indices[i]],out);
    }
    const flann::Matrix<float> m (data ,indices.size (), point_representation_->getNumberOfDimensions ());

    flann::SearchParams p;
    p.eps = eps_;
    index_->knnSearch (m,k_indices,k_sqr_distances,k, p);

    delete[] data;
  }
  if (!identity_mapping_)
  {
    for (size_t j = 0; j < k_indices.size (); ++j)
    {
      for (size_t i = 0; i < (size_t)k; ++i)
      {
        int& neighbor_index = k_indices[j][i];
        neighbor_index = index_mapping_[neighbor_index];
      }
    }
  }
}

//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> int
pcl::search::FlannSearch<PointT>::radiusSearch (const PointT& point, double radius,
    std::vector<int> &indices, std::vector<float> &distances,
    int max_nn) const
{
  bool can_cast = point_representation_->isTrivial ();

  float* data = 0;
  if (!can_cast)
  {
    data = new float [point_representation_->getNumberOfDimensions ()];
    point_representation_->vectorize (point,data);
  }

  float* cdata = can_cast ? const_cast<float*> (reinterpret_cast<const float*> (&point)) : data;
  const flann::Matrix<float> m (cdata ,1, point_representation_->getNumberOfDimensions ());

  flann::SearchParams p;
  p.eps = eps_;
  p.max_neighbors = max_nn;
  std::vector<std::vector<int> > i (1);
  std::vector<std::vector<float> > d (1);
  int result = index_->radiusSearch (m,i,d,radius*radius, p);

  delete [] data;
  indices=i [0];
  distances=d [0];

  if (!identity_mapping_)
  {
    for (size_t i = 0; i < indices.size (); ++i)
    {
      int& neighbor_index = indices [i];
      neighbor_index = index_mapping_ [neighbor_index];
    }
  }
  return result;
}

//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> void
pcl::search::FlannSearch<PointT>::radiusSearch (
    const PointCloud& cloud, const std::vector<int>& indices, double radius, std::vector< std::vector<int> >& k_indices,
    std::vector< std::vector<float> >& k_sqr_distances, int max_nn)
{
  if (indices.empty ()) // full point cloud + trivial copy operation = no need to do any conversion/copying to the flann matrix!
  {
    k_indices.resize (cloud.size ());
    k_sqr_distances.resize (cloud.size ());

    bool can_cast = point_representation_->isTrivial ();

    float* data = 0;
    if (!can_cast)
    {
      data = new float[dim_*cloud.size ()];
      for (size_t i = 0; i < cloud.size (); ++i)
      {
        float* out = data+i*dim_;
        point_representation_->vectorize (cloud[i],out);
      }
    }

    float* cdata = can_cast ? const_cast<float*> (reinterpret_cast<const float*> (&cloud[0])) : data;
    const flann::Matrix<float> m (cdata ,cloud.size (), dim_, can_cast ? sizeof (PointT) : dim_ * sizeof (float));

    flann::SearchParams p;
    p.eps = eps_;
    p.max_neighbors = max_nn;
    index_->radiusSearch (m,k_indices,k_sqr_distances,radius*radius, p);

    delete [] data;
  }
  else // if indices are present, the cloud has to be copied anyway. Only copy the relevant parts of the points here.
  {
    k_indices.resize (indices.size ());
    k_sqr_distances.resize (indices.size ());

    float* data = new float [dim_ * indices.size ()];
    for (size_t i = 0; i < indices.size (); ++i)
    {
      float* out = data+i*dim_;
      point_representation_->vectorize (cloud[indices[i]], out);
    }
    const flann::Matrix<float> m (data, cloud.size (), point_representation_->getNumberOfDimensions ());

    flann::SearchParams p;
    p.eps = eps_;
    p.max_neighbors = max_nn;
    index_->radiusSearch (m, k_indices, k_sqr_distances, radius * radius, p);

    delete[] data;
  }
  if (!identity_mapping_)
  {
    for (size_t j = 0; j < k_indices.size (); ++j )
    {
      for (size_t i = 0; i < k_indices[j].size (); ++i)
      {
        int& neighbor_index = k_indices[j][i];
        neighbor_index = index_mapping_[neighbor_index];
      }
    }
  }
}

//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> void
pcl::search::FlannSearch<PointT>::convertInputToFlannMatrix ()
{
  int original_no_of_points = indices_ && !indices_->empty () ? indices_->size () : input_->size ();

  if (input_copied_for_flann_)
    delete input_flann_.ptr();
  input_copied_for_flann_ = true;
  identity_mapping_ = true;

  input_flann_ = flann::Matrix<float> (new float[original_no_of_points*point_representation_->getNumberOfDimensions ()], original_no_of_points, point_representation_->getNumberOfDimensions ());

  //cloud_ = (float*)malloc (original_no_of_points * dim_ * sizeof (float));
  float* cloud_ptr = input_flann_.ptr();
  //index_mapping_.reserve(original_no_of_points);
  //identity_mapping_ = true;

  if (!indices_ || indices_->empty ())
  {
    /// TODO: implement "no NaN check" option that just re-uses the cloud data in the flann matrix
    for (int i = 0; i < original_no_of_points; ++i)
    {
      const PointT& point = (*input_)[i];
      // Check if the point is invalid
      if (!point_representation_->isValid (point))
      {
        identity_mapping_ = false;
        continue;
      }

      index_mapping_.push_back (i);  // If the returned index should be for the indices vector

      point_representation_->vectorize (point, cloud_ptr);
      cloud_ptr += dim_;
    }

  }
  else
  {
    for (int indices_index = 0; indices_index < original_no_of_points; ++indices_index)
    {
      int cloud_index = (*indices_)[indices_index];
      const PointT&  point = (*input_)[cloud_index];
      // Check if the point is invalid
      if (!point_representation_->isValid (point))
      {
        identity_mapping_ = false;
        continue;
      }

      index_mapping_.push_back (indices_index);  // If the returned index should be for the indices vector

      point_representation_->vectorize (point, cloud_ptr);
      cloud_ptr += dim_;
    }
  }
  input_flann_.rows = index_mapping_.size ();
}

#define PCL_INSTANTIATE_FlannSearch(T) template class PCL_EXPORTS pcl::search::FlannSearch<T>;

#endif
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: ConnectionPageSetup.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: rt $ $Date: 2007-04-26 07:56:11 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_dbaccess.hxx"

#ifndef DBAUI_CONNECTIONPAGESETUP_HXX
#include "ConnectionPageSetup.hxx"
#endif
#ifndef _DBAUI_AUTOCONTROLS_HRC_
#include "AutoControls.hrc"
#endif
#ifndef _DBAUI_DBADMINSETUP_HRC_
#include "dbadminsetup.hrc"
#endif
#ifndef _DBAUI_MODULE_DBU_HXX_
#include "moduledbu.hxx"
#endif
#ifndef _DBU_DLG_HRC_
#include "dbu_dlg.hrc"
#endif
#ifndef _SFXITEMSET_HXX
#include <svtools/itemset.hxx>
#endif
#ifndef INCLUDED_SVTOOLS_PATHOPTIONS_HXX
#include <svtools/pathoptions.hxx>
#endif
#ifndef _SFXSTRITEM_HXX
#include <svtools/stritem.hxx>
#endif
#ifndef _SFXENUMITEM_HXX
#include <svtools/eitem.hxx>
#endif
#ifndef _SFXINTITEM_HXX
#include <svtools/intitem.hxx>
#endif
#ifndef _DBAUI_DATASOURCEITEMS_HXX_
#include "dsitems.hxx"
#endif
#ifndef _DBA_DBACCESS_HELPID_HRC_
#include "dbaccess_helpid.hrc"
#endif
#ifndef _DBAUI_LOCALRESACCESS_HXX_
#include "localresaccess.hxx"
#endif
#ifndef _OSL_PROCESS_H_
#include <osl/process.h>
#endif
#ifndef _SV_MSGBOX_HXX
#include <vcl/msgbox.hxx>
#endif
#ifndef _FILEDLGHELPER_HXX
#include <sfx2/filedlghelper.hxx>
#endif
#ifndef _DBAUI_DBADMIN_HXX_
#include "dbadmin.hxx"
#endif
#ifndef _DBAUI_DBADMIN_HRC_
#include "dbadmin.hrc"
#endif
#ifndef _COMPHELPER_TYPES_HXX_
#include <comphelper/types.hxx>
#endif
#ifndef _VCL_STDTEXT_HXX
#include <vcl/stdtext.hxx>
#endif
#ifndef _DBAUI_SQLMESSAGE_HXX_
#include "sqlmessage.hxx"
#endif
#ifndef _DBAUI_ODBC_CONFIG_HXX_
#include "odbcconfig.hxx"
#endif
#ifndef _DBAUI_DSSELECT_HXX_
#include "dsselect.hxx"
#endif
#ifndef SVTOOLS_FILENOTATION_HXX_
#include <svtools/filenotation.hxx>
#endif
#ifndef DBACCESS_SHARED_DBUSTRINGS_HRC
#include "dbustrings.hrc"
#endif
#ifndef _COM_SUN_STAR_UI_DIALOGS_XFOLDERPICKER_HPP_
#include <com/sun/star/ui/dialogs/XFolderPicker.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBC_XROW_HPP_
#include <com/sun/star/sdbc/XRow.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_XWINDOW_HPP_
#include <com/sun/star/awt/XWindow.hpp>
#endif
// #106016# ------------------------------------
#ifndef _COM_SUN_STAR_TASK_XINTERACTIONHANDLER_HPP_
#include <com/sun/star/task/XInteractionHandler.hpp>
#endif
#ifndef _COM_SUN_STAR_TASK_XPROGRESSHANDLER_HPP_
#include <com/sun/star/ucb/XProgressHandler.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBC_XCONNECTION_HPP_
#include <com/sun/star/sdbc/XConnection.hpp>
#endif
#ifndef DBAUI_TOOLS_HXX
#include "UITools.hxx"
#endif
#ifndef _UNOTOOLS_LOCALFILEHELPER_HXX
#include <unotools/localfilehelper.hxx>
#endif
#ifndef _UNOTOOLS_UCBHELPER_HXX
#include <unotools/ucbhelper.hxx>
#endif
#ifndef _UCBHELPER_COMMANDENVIRONMENT_HXX
#include <ucbhelper/commandenvironment.hxx>
#endif
#ifndef DBAUI_FILEPICKER_INTERACTION_HXX
#include "finteraction.hxx"
#endif
#ifndef _CONNECTIVITY_COMMONTOOLS_HXX_
#include <connectivity/CommonTools.hxx>
#endif
#ifndef _URLOBJ_HXX
#include <tools/urlobj.hxx>
#endif
#ifndef _SFX_DOCFILT_HACK_HXX
#include <sfx2/docfilt.hxx>
#endif
#ifndef _SV_MNEMONIC_HXX
#include <vcl/mnemonic.hxx>
#endif

//.........................................................................
namespace dbaui
{
//.........................................................................
    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::ucb;
    using namespace ::com::sun::star::ui::dialogs;
    using namespace ::com::sun::star::sdbc;
    using namespace ::com::sun::star::beans;
    using namespace ::com::sun::star::lang;
    using namespace ::com::sun::star::container;
    using namespace ::dbtools;
    using namespace ::svt;

    OGenericAdministrationPage* OConnectionTabPageSetup::CreateDbaseTabPage( Window* pParent, const SfxItemSet& _rAttrSet )
    {
        OConnectionTabPageSetup* oDBWizardPage = new OConnectionTabPageSetup( pParent, PAGE_DBWIZARD_DBASE,    _rAttrSet, STR_DBASE_HELPTEXT,    STR_DBASE_HEADERTEXT,    STR_DBASE_PATH_OR_FILE);
        oDBWizardPage->FreeResource();
        return oDBWizardPage;
    }

    OGenericAdministrationPage* OConnectionTabPageSetup::CreateMSAccessTabPage( Window* pParent, const SfxItemSet& _rAttrSet )
    {
        OConnectionTabPageSetup* oDBWizardPage = new OConnectionTabPageSetup( pParent, PAGE_DBWIZARD_MSACCESS, _rAttrSet, STR_MSACCESS_HELPTEXT, STR_MSACCESS_HEADERTEXT, STR_MSACCESS_MDB_FILE);
        oDBWizardPage->FreeResource();
        return oDBWizardPage;
    }

    OGenericAdministrationPage* OConnectionTabPageSetup::CreateAdabasTabPage( Window* pParent,  const SfxItemSet& _rAttrSet )
    {
        OConnectionTabPageSetup* oDBWizardPage = new OConnectionTabPageSetup( pParent, PAGE_DBWIZARD_ADABAS, _rAttrSet, STR_ADABAS_HELPTEXT, STR_ADABAS_HEADERTEXT, STR_ADABAS_DATABASE_NAME);
        oDBWizardPage->FreeResource();
        return oDBWizardPage;
    }

    OGenericAdministrationPage* OConnectionTabPageSetup::CreateADOTabPage( Window* pParent, const SfxItemSet& _rAttrSet )
    {
        OConnectionTabPageSetup* oDBWizardPage = new OConnectionTabPageSetup( pParent, PAGE_DBWIZARD_ADO, _rAttrSet, STR_ADO_HELPTEXT, STR_ADO_HEADERTEXT, STR_COMMONURL);
        oDBWizardPage->FreeResource();
        return oDBWizardPage;
    }

    OGenericAdministrationPage* OConnectionTabPageSetup::CreateODBCTabPage( Window* pParent, const SfxItemSet& _rAttrSet )
    {
        OConnectionTabPageSetup* oDBWizardPage = new OConnectionTabPageSetup( pParent, PAGE_DBWIZARD_ODBC, _rAttrSet, STR_ODBC_HELPTEXT, STR_ODBC_HEADERTEXT, STR_NAME_OF_ODBC_DATASOURCE);
        oDBWizardPage->FreeResource();
        return oDBWizardPage;
    }

    OGenericAdministrationPage* OConnectionTabPageSetup::CreateUserDefinedTabPage( Window* pParent, const SfxItemSet& _rAttrSet )
    {
        OConnectionTabPageSetup* oDBWizardPage = new OConnectionTabPageSetup( pParent, PAGE_DBWIZARD_USERDEFINED, _rAttrSet, USHRT_MAX, USHRT_MAX, STR_COMMONURL);
        oDBWizardPage->FreeResource();
        return oDBWizardPage;
    }

    //========================================================================
    //= OConnectionTabPageSetup
    //========================================================================
    DBG_NAME(OConnectionTabPageSetup)
    OConnectionTabPageSetup::OConnectionTabPageSetup(Window* pParent, USHORT _rId, const SfxItemSet& _rCoreAttrs, USHORT _nHelpTextResId, USHORT _nHeaderResId, USHORT _nUrlResId)
        :OConnectionHelper(pParent, ModuleRes(_rId), _rCoreAttrs)
        ,m_bUserGrabFocus(sal_True)
        ,m_aFT_HelpText(this, ModuleRes(FT_AUTOWIZARDHELPTEXT))
    {
        DBG_CTOR(OConnectionTabPageSetup, NULL);

        if ( USHRT_MAX != _nHelpTextResId )
        {
            String sHelpText = String(ModuleRes(_nHelpTextResId));
            m_aFT_HelpText.SetText(sHelpText);
        }
        else
            m_aFT_HelpText.Hide();

        if ( USHRT_MAX != _nHeaderResId )
            SetHeaderText(this, FT_AUTOWIZARDHEADER, _nHeaderResId);

        if ( USHRT_MAX != _nUrlResId )
        {
            String sLabelText = String(ModuleRes(_nUrlResId));
            m_aFT_Connection.SetText(sLabelText);
            if ( USHRT_MAX == _nHelpTextResId )
            {
                Point aPos = m_aFT_HelpText.GetPosPixel();
                Point aFTPos = m_aFT_Connection.GetPosPixel();
                Point aEDPos = m_aET_Connection.GetPosPixel();
                Point aPBPos = m_aPB_Connection.GetPosPixel();

                aEDPos.Y() = aPos.Y() + aEDPos.Y() - aFTPos.Y();
                aPBPos.Y() = aPos.Y() + aPBPos.Y() - aFTPos.Y();
                aFTPos.Y() = aPos.Y();
                m_aFT_Connection.SetPosPixel(aFTPos);
                m_aET_Connection.SetPosPixel(aEDPos);
                m_aPB_Connection.SetPosPixel(aPBPos);
            }
        }
        else
            m_aFT_Connection.Hide();

        m_aET_Connection.SetModifyHdl(LINK(this, OConnectionTabPageSetup, OnEditModified));

        SetRoadmapStateValue(sal_False);
    }

    // -----------------------------------------------------------------------
    OConnectionTabPageSetup::~OConnectionTabPageSetup()
    {
        DBG_DTOR(OConnectionTabPageSetup,NULL);
    }

    // -----------------------------------------------------------------------
    void OConnectionTabPageSetup::implInitControls(const SfxItemSet& _rSet, sal_Bool _bSaveValue)
    {
        m_eType = m_pAdminDialog->getDatasourceType(_rSet);
        // special handling for oracle, this can only happen
        // if the user enters the same url as used for Oracle and we are on the JDBC path
        if ( DST_ORACLE_JDBC == m_eType )
            m_eType = DST_JDBC;

        OConnectionHelper::implInitControls(_rSet, _bSaveValue);

        if ( m_eType >= DST_USERDEFINE1 )
        {
            String sDisplayName = m_pCollection->getTypeDisplayName(m_eType);
            FixedText* ppTextControls[] ={&m_aFT_Connection};
            for (size_t i = 0; i < sizeof(ppTextControls)/sizeof(ppTextControls[0]); ++i)
            {
                ppTextControls[i]->SetText(sDisplayName);
            }
        }

        callModifiedHdl();
    }
    // -----------------------------------------------------------------------
       sal_Bool OConnectionTabPageSetup::commitPage(COMMIT_REASON /*_eReason*/)
    {
        return commitURL();
    }

    // -----------------------------------------------------------------------
    sal_Bool OConnectionTabPageSetup::FillItemSet(SfxItemSet& _rSet)
    {
        sal_Bool bChangedSomething = sal_False;
        fillString(_rSet,&m_aET_Connection, DSID_CONNECTURL, bChangedSomething);
        return bChangedSomething;
    }
    // -----------------------------------------------------------------------
    bool OConnectionTabPageSetup::checkTestConnection()
    {
        return !m_aET_Connection.IsVisible() || (m_aET_Connection.GetTextNoPrefix().Len() != 0);
    }

    // -----------------------------------------------------------------------
    IMPL_LINK(OConnectionTabPageSetup, OnEditModified, Edit*, /*_pEdit*/)
    {
        SetRoadmapStateValue(checkTestConnection());
        callModifiedHdl();
        return 0L;
    }

    // -----------------------------------------------------------------------
    void OConnectionTabPageSetup::toggleURLControlGroup(BOOL _bEnable)
    {
        m_aET_Connection.Enable(_bEnable);
        m_aPB_Connection.Enable(_bEnable);
        m_aFT_Connection.Enable(_bEnable);
    }

//.........................................................................
}   // namespace dbaui
//.........................................................................

<commit_msg>INTEGRATION: CWS dba23a (1.7.72); FILE MERGED 2007/03/13 08:42:12 fs 1.7.72.2: some slight re-factoring (class/method renaming), plus some rudimentary fix for #b6532894# 2007/02/26 10:34:00 fs 1.7.72.1: remove unused code Issue number:  #i74776# Submitted by:  jnavrati@openoffice.org Reviewed by:   frank.schoenheit@sun.com<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: ConnectionPageSetup.cxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: kz $ $Date: 2007-05-10 10:22:01 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_dbaccess.hxx"

#ifndef DBAUI_CONNECTIONPAGESETUP_HXX
#include "ConnectionPageSetup.hxx"
#endif
#ifndef _DBAUI_AUTOCONTROLS_HRC_
#include "AutoControls.hrc"
#endif
#ifndef _DBAUI_DBADMINSETUP_HRC_
#include "dbadminsetup.hrc"
#endif
#ifndef _DBAUI_MODULE_DBU_HXX_
#include "moduledbu.hxx"
#endif
#ifndef _DBU_DLG_HRC_
#include "dbu_dlg.hrc"
#endif
#ifndef _SFXITEMSET_HXX
#include <svtools/itemset.hxx>
#endif
#ifndef INCLUDED_SVTOOLS_PATHOPTIONS_HXX
#include <svtools/pathoptions.hxx>
#endif
#ifndef _SFXSTRITEM_HXX
#include <svtools/stritem.hxx>
#endif
#ifndef _SFXENUMITEM_HXX
#include <svtools/eitem.hxx>
#endif
#ifndef _SFXINTITEM_HXX
#include <svtools/intitem.hxx>
#endif
#ifndef _DBAUI_DATASOURCEITEMS_HXX_
#include "dsitems.hxx"
#endif
#ifndef _DBA_DBACCESS_HELPID_HRC_
#include "dbaccess_helpid.hrc"
#endif
#ifndef _DBAUI_LOCALRESACCESS_HXX_
#include "localresaccess.hxx"
#endif
#ifndef _OSL_PROCESS_H_
#include <osl/process.h>
#endif
#ifndef _SV_MSGBOX_HXX
#include <vcl/msgbox.hxx>
#endif
#ifndef _FILEDLGHELPER_HXX
#include <sfx2/filedlghelper.hxx>
#endif
#ifndef _DBAUI_DBADMIN_HXX_
#include "dbadmin.hxx"
#endif
#ifndef _DBAUI_DBADMIN_HRC_
#include "dbadmin.hrc"
#endif
#ifndef _COMPHELPER_TYPES_HXX_
#include <comphelper/types.hxx>
#endif
#ifndef _VCL_STDTEXT_HXX
#include <vcl/stdtext.hxx>
#endif
#ifndef _DBAUI_SQLMESSAGE_HXX_
#include "sqlmessage.hxx"
#endif
#ifndef _DBAUI_ODBC_CONFIG_HXX_
#include "odbcconfig.hxx"
#endif
#ifndef _DBAUI_DSSELECT_HXX_
#include "dsselect.hxx"
#endif
#ifndef SVTOOLS_FILENOTATION_HXX_
#include <svtools/filenotation.hxx>
#endif
#ifndef DBACCESS_SHARED_DBUSTRINGS_HRC
#include "dbustrings.hrc"
#endif
#ifndef _COM_SUN_STAR_UI_DIALOGS_XFOLDERPICKER_HPP_
#include <com/sun/star/ui/dialogs/XFolderPicker.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBC_XROW_HPP_
#include <com/sun/star/sdbc/XRow.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_XWINDOW_HPP_
#include <com/sun/star/awt/XWindow.hpp>
#endif
// #106016# ------------------------------------
#ifndef _COM_SUN_STAR_TASK_XINTERACTIONHANDLER_HPP_
#include <com/sun/star/task/XInteractionHandler.hpp>
#endif
#ifndef _COM_SUN_STAR_TASK_XPROGRESSHANDLER_HPP_
#include <com/sun/star/ucb/XProgressHandler.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBC_XCONNECTION_HPP_
#include <com/sun/star/sdbc/XConnection.hpp>
#endif
#ifndef DBAUI_TOOLS_HXX
#include "UITools.hxx"
#endif
#ifndef _UNOTOOLS_LOCALFILEHELPER_HXX
#include <unotools/localfilehelper.hxx>
#endif
#ifndef _UNOTOOLS_UCBHELPER_HXX
#include <unotools/ucbhelper.hxx>
#endif
#ifndef _UCBHELPER_COMMANDENVIRONMENT_HXX
#include <ucbhelper/commandenvironment.hxx>
#endif
#ifndef DBAUI_FILEPICKER_INTERACTION_HXX
#include "finteraction.hxx"
#endif
#ifndef _CONNECTIVITY_COMMONTOOLS_HXX_
#include <connectivity/CommonTools.hxx>
#endif
#ifndef _URLOBJ_HXX
#include <tools/urlobj.hxx>
#endif
#ifndef _SFX_DOCFILT_HACK_HXX
#include <sfx2/docfilt.hxx>
#endif
#ifndef _SV_MNEMONIC_HXX
#include <vcl/mnemonic.hxx>
#endif

//.........................................................................
namespace dbaui
{
//.........................................................................
    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::ucb;
    using namespace ::com::sun::star::ui::dialogs;
    using namespace ::com::sun::star::sdbc;
    using namespace ::com::sun::star::beans;
    using namespace ::com::sun::star::lang;
    using namespace ::com::sun::star::container;
    using namespace ::dbtools;
    using namespace ::svt;

    OGenericAdministrationPage* OConnectionTabPageSetup::CreateDbaseTabPage( Window* pParent, const SfxItemSet& _rAttrSet )
    {
        OConnectionTabPageSetup* oDBWizardPage = new OConnectionTabPageSetup( pParent, PAGE_DBWIZARD_DBASE,    _rAttrSet, STR_DBASE_HELPTEXT,    STR_DBASE_HEADERTEXT,    STR_DBASE_PATH_OR_FILE);
        oDBWizardPage->FreeResource();
        return oDBWizardPage;
    }

    OGenericAdministrationPage* OConnectionTabPageSetup::CreateMSAccessTabPage( Window* pParent, const SfxItemSet& _rAttrSet )
    {
        OConnectionTabPageSetup* oDBWizardPage = new OConnectionTabPageSetup( pParent, PAGE_DBWIZARD_MSACCESS, _rAttrSet, STR_MSACCESS_HELPTEXT, STR_MSACCESS_HEADERTEXT, STR_MSACCESS_MDB_FILE);
        oDBWizardPage->FreeResource();
        return oDBWizardPage;
    }

    OGenericAdministrationPage* OConnectionTabPageSetup::CreateAdabasTabPage( Window* pParent,  const SfxItemSet& _rAttrSet )
    {
        OConnectionTabPageSetup* oDBWizardPage = new OConnectionTabPageSetup( pParent, PAGE_DBWIZARD_ADABAS, _rAttrSet, STR_ADABAS_HELPTEXT, STR_ADABAS_HEADERTEXT, STR_ADABAS_DATABASE_NAME);
        oDBWizardPage->FreeResource();
        return oDBWizardPage;
    }

    OGenericAdministrationPage* OConnectionTabPageSetup::CreateADOTabPage( Window* pParent, const SfxItemSet& _rAttrSet )
    {
        OConnectionTabPageSetup* oDBWizardPage = new OConnectionTabPageSetup( pParent, PAGE_DBWIZARD_ADO, _rAttrSet, STR_ADO_HELPTEXT, STR_ADO_HEADERTEXT, STR_COMMONURL);
        oDBWizardPage->FreeResource();
        return oDBWizardPage;
    }

    OGenericAdministrationPage* OConnectionTabPageSetup::CreateODBCTabPage( Window* pParent, const SfxItemSet& _rAttrSet )
    {
        OConnectionTabPageSetup* oDBWizardPage = new OConnectionTabPageSetup( pParent, PAGE_DBWIZARD_ODBC, _rAttrSet, STR_ODBC_HELPTEXT, STR_ODBC_HEADERTEXT, STR_NAME_OF_ODBC_DATASOURCE);
        oDBWizardPage->FreeResource();
        return oDBWizardPage;
    }

    OGenericAdministrationPage* OConnectionTabPageSetup::CreateUserDefinedTabPage( Window* pParent, const SfxItemSet& _rAttrSet )
    {
        OConnectionTabPageSetup* oDBWizardPage = new OConnectionTabPageSetup( pParent, PAGE_DBWIZARD_USERDEFINED, _rAttrSet, USHRT_MAX, USHRT_MAX, STR_COMMONURL);
        oDBWizardPage->FreeResource();
        return oDBWizardPage;
    }

    //========================================================================
    //= OConnectionTabPageSetup
    //========================================================================
    DBG_NAME(OConnectionTabPageSetup)
    OConnectionTabPageSetup::OConnectionTabPageSetup(Window* pParent, USHORT _rId, const SfxItemSet& _rCoreAttrs, USHORT _nHelpTextResId, USHORT _nHeaderResId, USHORT _nUrlResId)
        :OConnectionHelper(pParent, ModuleRes(_rId), _rCoreAttrs)
        ,m_bUserGrabFocus(sal_True)
        ,m_aFT_HelpText(this, ModuleRes(FT_AUTOWIZARDHELPTEXT))
    {
        DBG_CTOR(OConnectionTabPageSetup, NULL);

        if ( USHRT_MAX != _nHelpTextResId )
        {
            String sHelpText = String(ModuleRes(_nHelpTextResId));
            m_aFT_HelpText.SetText(sHelpText);
        }
        else
            m_aFT_HelpText.Hide();

        if ( USHRT_MAX != _nHeaderResId )
            SetHeaderText(FT_AUTOWIZARDHEADER, _nHeaderResId);

        if ( USHRT_MAX != _nUrlResId )
        {
            String sLabelText = String(ModuleRes(_nUrlResId));
            m_aFT_Connection.SetText(sLabelText);
            if ( USHRT_MAX == _nHelpTextResId )
            {
                Point aPos = m_aFT_HelpText.GetPosPixel();
                Point aFTPos = m_aFT_Connection.GetPosPixel();
                Point aEDPos = m_aET_Connection.GetPosPixel();
                Point aPBPos = m_aPB_Connection.GetPosPixel();

                aEDPos.Y() = aPos.Y() + aEDPos.Y() - aFTPos.Y();
                aPBPos.Y() = aPos.Y() + aPBPos.Y() - aFTPos.Y();
                aFTPos.Y() = aPos.Y();
                m_aFT_Connection.SetPosPixel(aFTPos);
                m_aET_Connection.SetPosPixel(aEDPos);
                m_aPB_Connection.SetPosPixel(aPBPos);
            }
        }
        else
            m_aFT_Connection.Hide();

        m_aET_Connection.SetModifyHdl(LINK(this, OConnectionTabPageSetup, OnEditModified));

        SetRoadmapStateValue(sal_False);
    }

    // -----------------------------------------------------------------------
    OConnectionTabPageSetup::~OConnectionTabPageSetup()
    {
        DBG_DTOR(OConnectionTabPageSetup,NULL);
    }

    // -----------------------------------------------------------------------
    void OConnectionTabPageSetup::implInitControls(const SfxItemSet& _rSet, sal_Bool _bSaveValue)
    {
        m_eType = m_pAdminDialog->getDatasourceType(_rSet);
        // special handling for oracle, this can only happen
        // if the user enters the same url as used for Oracle and we are on the JDBC path
        if ( DST_ORACLE_JDBC == m_eType )
            m_eType = DST_JDBC;

        OConnectionHelper::implInitControls(_rSet, _bSaveValue);

        if ( m_eType >= DST_USERDEFINE1 )
        {
            String sDisplayName = m_pCollection->getTypeDisplayName(m_eType);
            FixedText* ppTextControls[] ={&m_aFT_Connection};
            for (size_t i = 0; i < sizeof(ppTextControls)/sizeof(ppTextControls[0]); ++i)
            {
                ppTextControls[i]->SetText(sDisplayName);
            }
        }

        callModifiedHdl();
    }
    // -----------------------------------------------------------------------
       sal_Bool OConnectionTabPageSetup::commitPage(COMMIT_REASON /*_eReason*/)
    {
        return commitURL();
    }

    // -----------------------------------------------------------------------
    sal_Bool OConnectionTabPageSetup::FillItemSet(SfxItemSet& _rSet)
    {
        sal_Bool bChangedSomething = sal_False;
        fillString(_rSet,&m_aET_Connection, DSID_CONNECTURL, bChangedSomething);
        return bChangedSomething;
    }
    // -----------------------------------------------------------------------
    bool OConnectionTabPageSetup::checkTestConnection()
    {
        return !m_aET_Connection.IsVisible() || (m_aET_Connection.GetTextNoPrefix().Len() != 0);
    }

    // -----------------------------------------------------------------------
    IMPL_LINK(OConnectionTabPageSetup, OnEditModified, Edit*, /*_pEdit*/)
    {
        SetRoadmapStateValue(checkTestConnection());
        callModifiedHdl();
        return 0L;
    }
//.........................................................................
}   // namespace dbaui
//.........................................................................

<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkImageMandelbrotSource.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) 1993-2002 Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkImageMandelbrotSource.h"
#include "vtkImageData.h"
#include "vtkObjectFactory.h"

vtkCxxRevisionMacro(vtkImageMandelbrotSource, "1.30");
vtkStandardNewMacro(vtkImageMandelbrotSource);

//----------------------------------------------------------------------------
vtkImageMandelbrotSource::vtkImageMandelbrotSource()
{
  this->MaximumNumberOfIterations = 100;
  this->WholeExtent[0] = 0;
  this->WholeExtent[1] = 250;
  this->WholeExtent[2] = 0;
  this->WholeExtent[3] = 250;
  this->WholeExtent[4] = 0;
  this->WholeExtent[5] = 0;

  this->SampleCX[0] = 0.01;
  this->SampleCX[1] = 0.01;
  this->SampleCX[2] = 0.01;
  this->SampleCX[3] = 0.01;

  this->OriginCX[0] = -1.75;
  this->OriginCX[1] = -1.25;
  this->OriginCX[2] = 0.0;
  this->OriginCX[3] = 0.0;

  this->ProjectionAxes[0] = 0;
  this->ProjectionAxes[1] = 1;
  this->ProjectionAxes[2] = 2;
}

//----------------------------------------------------------------------------
vtkImageMandelbrotSource::~vtkImageMandelbrotSource()
{
}

//----------------------------------------------------------------------------
void vtkImageMandelbrotSource::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);

  os << indent << "OriginC: (" << this->OriginCX[0] << ", "
     << this->OriginCX[1] << ")\n";
  os << indent << "OriginX: (" << this->OriginCX[2] << ", "
     << this->OriginCX[3] << ")\n";

  os << indent << "SampleC: (" << this->SampleCX[0] << ", "
     << this->SampleCX[1] << ")\n";
  os << indent << "SampleX: (" << this->SampleCX[2] << ", "
     << this->SampleCX[3] << ")\n";

  os << indent << "WholeExtent: (" << this->WholeExtent[0] << ", "
     << this->WholeExtent[1] << ", " << this->WholeExtent[2] << ", "
     << this->WholeExtent[3] << ", " << this->WholeExtent[4] << ", "
     << this->WholeExtent[5] << ")\n";
  os << "MaximumNumberOfIterations: " << this->MaximumNumberOfIterations << endl;

  os << indent << "ProjectionAxes: (" << this->ProjectionAxes[0] << ", "
     << this->ProjectionAxes[1] << this->ProjectionAxes[2] << ")\n";

}

//----------------------------------------------------------------------------
/*
void vtkImageMandelbrotSource::SetOriginCX(double cReal, double cImag,
                                           double xReal, double xImag)
{
  int modified = 0;

  if (cReal != this->OriginCX[0])
    {
    this->OriginCX[0]  = cReal;
    modified = 1;
    }
  if (cImag != this->OriginCX[1])
    {
    this->OriginCX[1]  = cImag;
    modified = 1;
    }
  if (xReal != this->OriginCX[2])
    {
    this->OriginCX[2]  = xReal;
    modified = 1;
    }
  if (xImag != this->OriginCX[3])
    {
    this->OriginCX[3]  = xImag;
    modified = 1;
    }

  if (modified)
    {
    this->Modified();
    }
}
*/
//----------------------------------------------------------------------------
void vtkImageMandelbrotSource::SetWholeExtent(int extent[6])
{
  int idx, modified = 0;

  for (idx = 0; idx < 6; ++idx)
    {
    if (this->WholeExtent[idx] != extent[idx])
      {
      this->WholeExtent[idx] = extent[idx];
      this->Modified();
      }
    }
  if (modified)
    {
    this->Modified();
    }
}

//----------------------------------------------------------------------------
void vtkImageMandelbrotSource::SetWholeExtent(int minX, int maxX,
                                            int minY, int maxY,
                                            int minZ, int maxZ)
{
  int extent[6];

  extent[0] = minX;  extent[1] = maxX;
  extent[2] = minY;  extent[3] = maxY;
  extent[4] = minZ;  extent[5] = maxZ;
  this->SetWholeExtent(extent);
}

//----------------------------------------------------------------------------
void vtkImageMandelbrotSource::ExecuteInformation()
{
  int idx, axis;
  float origin[3];
  float spacing[3];
  vtkImageData *output = this->GetOutput();

  output->SetWholeExtent(this->WholeExtent);
  for (idx = 0; idx < 3; ++idx)
    {
    axis = this->ProjectionAxes[idx];
    if (axis >= 0 && axis < 4)
      {
      origin[idx] = this->OriginCX[axis];
      spacing[idx] = this->SampleCX[axis];
      }
    else
      {
      vtkErrorMacro("Bad projection axis.");
      origin[idx] = 0.0;
      spacing[idx] = 1.0;
      }
    }

  output->SetSpacing(spacing);
  output->SetOrigin(origin);
  output->SetNumberOfScalarComponents(1);
  output->SetScalarType(VTK_FLOAT);
}

//----------------------------------------------------------------------------
// We may want separate zooms for mandelbrot and julia.
void vtkImageMandelbrotSource::Zoom(double factor)
{
  if (factor == 1.0)
    {
    return;
    }
  this->Modified();
  this->SampleCX[0] *= factor;
  this->SampleCX[1] *= factor;
  this->SampleCX[2] *= factor;
  this->SampleCX[3] *= factor;
}

//----------------------------------------------------------------------------
void vtkImageMandelbrotSource::Pan(double x, double y, double z)
{
  int idx, axis;
  double pan[3];

  if (x == 0.0 && y == 0.0 && z == 0.0)
    {
    return;
    }

  this->Modified();
  pan[0]=x;    pan[1]=y;    pan[2]=z;
  for (idx = 0; idx < 3; ++idx)
    {
    axis = this->ProjectionAxes[idx];
    if (axis >= 0 && axis < 4)
      {
      this->OriginCX[axis] += this->SampleCX[axis] * pan[idx];
      }
    }
}

//----------------------------------------------------------------------------
void
vtkImageMandelbrotSource::CopyOriginAndSample(vtkImageMandelbrotSource *source)
{
  int idx;

  for (idx = 0; idx < 4; ++idx)
    {
    this->OriginCX[idx] = source->OriginCX[idx];
    this->SampleCX[idx] = source->SampleCX[idx];
    }

  this->Modified();
}
//----------------------------------------------------------------------------
void vtkImageMandelbrotSource::ExecuteData(vtkDataObject *output)
{
  vtkImageData *data = this->AllocateOutputData(output);
  int *ext, a0, a1, a2;
  float *ptr;
  int min0, max0;
  int idx0, idx1, idx2;
  int inc0, inc1, inc2;
  double *origin, *sample;
  double p[4];
  unsigned long count = 0;
  unsigned long target;

  // Copy origin into pixel
  for (idx0 = 0; idx0 < 4; ++idx0)
    {
    p[idx0] = this->OriginCX[idx0];
    }

  ext = data->GetUpdateExtent();
  ptr = (float *)(data->GetScalarPointerForExtent(ext));

  vtkDebugMacro("Generating Extent: " << ext[0] << " -> " << ext[1] << ", "
                << ext[2] << " -> " << ext[3]);

  // Get min and max of axis 0 because it is the innermost loop.
  min0 = ext[0];
  max0 = ext[1];
  data->GetContinuousIncrements(ext, inc0, inc1, inc2);

  target = (unsigned long)((ext[5]-ext[4]+1)*(ext[3]-ext[2]+1)/50.0);
  target++;

  a0 = this->ProjectionAxes[0];
  a1 = this->ProjectionAxes[1];
  a2 = this->ProjectionAxes[2];
  origin = this->OriginCX;
  sample = this->SampleCX;

  if (a0<0 || a1<0 || a2<0 || a0>3 || a1>3 || a2>3)
    {
    vtkErrorMacro("Bad projection axis");
    return;
    }
  for (idx2 = ext[4]; idx2 <= ext[5]; ++idx2)
    {
    p[a2] = (double)(origin[a2]) + (double)(idx2)*(sample[a2]);
    for (idx1 = ext[2]; !this->AbortExecute && idx1 <= ext[3]; ++idx1)
      {
      if (!(count%target))
        {
        this->UpdateProgress(count/(50.0*target));
        }
      count++;
      p[a1] = (double)(origin[a1]) + (double)(idx1)*(sample[a1]);
      for (idx0 = min0; idx0 <= max0; ++idx0)
        {
        p[a0] = (double)(origin[a0]) + (double)(idx0)*(sample[a0]);

        *ptr = (float)(this->EvaluateSet(p));

        ++ptr;
        // inc0 is 0
        }
      ptr += inc1;
      }
    ptr += inc2;
    }

  // Name the array appropriately.
  data->GetPointData()->GetScalars()->SetName("Iterations");
}

//----------------------------------------------------------------------------
// This method selectively supersamples pixels closet to the mandelbrot set.
/*
void vtkImageMandelbrotSource::SuperSample(vtkImageData *data)
{
  int *ext;
  float *ptr0, *ptr1, *ptr2;
  int min0, max0;
  int idx0, idx1, idx2;
  int inc0, inc1, inc2;

  // Get min and max of axis 0 because it is the innermost loop.
  ext = data->GetUpdateExtent();
  min0 = ext[0];
  max0 = ext[1];
  data->GetIncrements(inc0, inc1, inc2);

  // loop through pixels ignoring the borders.
  ptr2 = (float *)(data->GetScalarPointer(min0+1, ext[2]+1, ext[4]+1));

  for (idx2 = ext[4]+1; idx2 < ext[5]; ++idx2)
    {
    ptr1 = ptr2;
    for (idx1 = ext[2]+1; idx1 < ext[3]; ++idx1)
      {
      ptr0 = ptr1;
      for (idx0 = min0+1; idx0 < max0; ++idx0)
        {
        *ptr0 = (float*)(this->EvaluateSet(p));

        ++ptr0;
        // inc0 is 1
        }
      ptr1 += inc1;
      }
    ptr2 += inc2;
    }
}
*/

//----------------------------------------------------------------------------
float vtkImageMandelbrotSource::EvaluateSet(double p[4])
{
  unsigned short count = 0;
  double v0, v1;
  double cReal, cImag, zReal, zImag;
  double zReal2, zImag2;

  cReal = p[0];
  cImag = p[1];
  zReal = p[2];
  zImag = p[3];

  zReal2 = zReal * zReal;
  zImag2 = zImag * zImag;
  v0 = 0.0;
  v1 = (zReal2 + zImag2);
  while ( v1 < 4.0 && count < this->MaximumNumberOfIterations)
    {
    zImag = 2.0 * zReal * zImag + cImag;
    zReal = zReal2 - zImag2 + cReal;
    zReal2 = zReal * zReal;
    zImag2 = zImag * zImag;
    ++count;
    v0 = v1;
    v1 = (zReal2 + zImag2);
    }

  if (count == this->MaximumNumberOfIterations)
    {
    return (float)count;
    }

  return (float)count + (4.0 - v0)/(v1 - v0);
}

<commit_msg>Missed this file yesterday.<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkImageMandelbrotSource.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) 1993-2002 Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkImageMandelbrotSource.h"
#include "vtkImageData.h"
#include "vtkObjectFactory.h"

vtkCxxRevisionMacro(vtkImageMandelbrotSource, "1.31");
vtkStandardNewMacro(vtkImageMandelbrotSource);

//----------------------------------------------------------------------------
vtkImageMandelbrotSource::vtkImageMandelbrotSource()
{
  this->MaximumNumberOfIterations = 100;
  this->WholeExtent[0] = 0;
  this->WholeExtent[1] = 250;
  this->WholeExtent[2] = 0;
  this->WholeExtent[3] = 250;
  this->WholeExtent[4] = 0;
  this->WholeExtent[5] = 0;

  this->SampleCX[0] = 0.01;
  this->SampleCX[1] = 0.01;
  this->SampleCX[2] = 0.01;
  this->SampleCX[3] = 0.01;

  this->SizeCX[0] = 2.5;
  this->SizeCX[1] = 2.5;
  this->SizeCX[2] = 2.5;
  this->SizeCX[3] = 2.5;

  this->ConstantSize = 1;

  this->OriginCX[0] = -1.75;
  this->OriginCX[1] = -1.25;
  this->OriginCX[2] = 0.0;
  this->OriginCX[3] = 0.0;

  this->ProjectionAxes[0] = 0;
  this->ProjectionAxes[1] = 1;
  this->ProjectionAxes[2] = 2;
}

//----------------------------------------------------------------------------
vtkImageMandelbrotSource::~vtkImageMandelbrotSource()
{
}

//----------------------------------------------------------------------------
void vtkImageMandelbrotSource::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);

  os << indent << "OriginC: (" << this->OriginCX[0] << ", "
     << this->OriginCX[1] << ")\n";
  os << indent << "OriginX: (" << this->OriginCX[2] << ", "
     << this->OriginCX[3] << ")\n";

  os << indent << "SampleC: (" << this->SampleCX[0] << ", "
     << this->SampleCX[1] << ")\n";
  os << indent << "SampleX: (" << this->SampleCX[2] << ", "
     << this->SampleCX[3] << ")\n";

  double *size = this->GetSizeCX();
  os << indent << "SizeC: (" << size[0] << ", " << size[1] << ")\n";
  os << indent << "SizeX: (" << size[2] << ", " << size[3] << ")\n";

  if (this->ConstantSize)
    {
    os << indent << "ConstantSize\n";
    }
  else
    {
    os << indent << "ConstantSpacing\n";
    }

  os << indent << "WholeExtent: (" << this->WholeExtent[0] << ", "
     << this->WholeExtent[1] << ", " << this->WholeExtent[2] << ", "
     << this->WholeExtent[3] << ", " << this->WholeExtent[4] << ", "
     << this->WholeExtent[5] << ")\n";
  os << "MaximumNumberOfIterations: " << this->MaximumNumberOfIterations << endl;

  os << indent << "ProjectionAxes: (" << this->ProjectionAxes[0] << ", "
     << this->ProjectionAxes[1] << this->ProjectionAxes[2] << ")\n";

}

//----------------------------------------------------------------------------
void vtkImageMandelbrotSource::SetWholeExtent(int extent[6])
{
  int idx, modified = 0;
  double saveSize[4];

  this->GetSizeCX(saveSize);

  for (idx = 0; idx < 6; ++idx)
    {
    if (this->WholeExtent[idx] != extent[idx])
      {
      this->WholeExtent[idx] = extent[idx];
      modified = 1;
      }
    }

  if (modified)
    {
    this->Modified();
    if (this->ConstantSize)
      {
      this->SetSizeCX(saveSize[0], saveSize[1], saveSize[2], saveSize[3]);
      }
    }
}

//----------------------------------------------------------------------------
void vtkImageMandelbrotSource::SetWholeExtent(int minX, int maxX,
                                            int minY, int maxY,
                                            int minZ, int maxZ)
{
  int extent[6];

  extent[0] = minX;  extent[1] = maxX;
  extent[2] = minY;  extent[3] = maxY;
  extent[4] = minZ;  extent[5] = maxZ;
  this->SetWholeExtent(extent);
}

//----------------------------------------------------------------------------
void vtkImageMandelbrotSource::SetSizeCX(double cReal, double cImag,
                                         double xReal, double xImag)
{
  int axis;
  int idx;
  int d;

  double *s = this->GetSizeCX();
  if (s[0] == cReal && s[1] == cImag && s[2] == xReal && s[3] == xImag)
    {
    return;
    }
  this->Modified();

  // Set this because information can be carried over for collapsed axes.
  this->SizeCX[0] = cReal;
  this->SizeCX[1] = cImag;
  this->SizeCX[2] = xReal;
  this->SizeCX[3] = xImag;

  // Now compute the gold standard (for non collapsed axes.
  for (idx = 0; idx < 3; ++idx)
    {
    d = this->WholeExtent[idx*2+1] - this->WholeExtent[idx*2];
    if (d > 0)
      {
      axis = this->ProjectionAxes[idx];
      this->SampleCX[axis] = this->SizeCX[axis] / ((double) d);
      }
    }
}

//----------------------------------------------------------------------------
double* vtkImageMandelbrotSource::GetSizeCX()
{
  int axis;
  int idx;
  int d;

  // Recompute the size for the spacing (gold standard).
  for (idx = 0; idx < 3; ++idx)
    {
    d = this->WholeExtent[idx*2+1] - this->WholeExtent[idx*2];
    if (d > 0)
      {
      axis = this->ProjectionAxes[idx];
      this->SizeCX[axis] = this->SampleCX[axis] * ((double) d);
      }
    }

  return this->SizeCX;
}

//----------------------------------------------------------------------------
void vtkImageMandelbrotSource::GetSizeCX(double s[4])
{
  double *p = this->GetSizeCX();

  s[0] = p[0];
  s[1] = p[1];
  s[2] = p[2];
  s[3] = p[3];
}

//----------------------------------------------------------------------------
void vtkImageMandelbrotSource::ExecuteInformation()
{
  int idx, axis;
  float origin[3];
  float spacing[3];
  vtkImageData *output = this->GetOutput();

  output->SetWholeExtent(this->WholeExtent);
  for (idx = 0; idx < 3; ++idx)
    {
    axis = this->ProjectionAxes[idx];
    if (axis >= 0 && axis < 4)
      {
      origin[idx] = this->OriginCX[axis];
      spacing[idx] = this->SampleCX[axis];
      }
    else
      {
      vtkErrorMacro("Bad projection axis.");
      origin[idx] = 0.0;
      spacing[idx] = 1.0;
      }
    }

  output->SetSpacing(spacing);
  output->SetOrigin(origin);
  output->SetNumberOfScalarComponents(1);
  output->SetScalarType(VTK_FLOAT);
}

//----------------------------------------------------------------------------
// We may want separate zooms for mandelbrot and julia.
void vtkImageMandelbrotSource::Zoom(double factor)
{
  if (factor == 1.0)
    {
    return;
    }
  this->Modified();
  this->SampleCX[0] *= factor;
  this->SampleCX[1] *= factor;
  this->SampleCX[2] *= factor;
  this->SampleCX[3] *= factor;
}

//----------------------------------------------------------------------------
void vtkImageMandelbrotSource::Pan(double x, double y, double z)
{
  int idx, axis;
  double pan[3];

  if (x == 0.0 && y == 0.0 && z == 0.0)
    {
    return;
    }

  this->Modified();
  pan[0]=x;    pan[1]=y;    pan[2]=z;
  for (idx = 0; idx < 3; ++idx)
    {
    axis = this->ProjectionAxes[idx];
    if (axis >= 0 && axis < 4)
      {
      this->OriginCX[axis] += this->SampleCX[axis] * pan[idx];
      }
    }
}

//----------------------------------------------------------------------------
void
vtkImageMandelbrotSource::CopyOriginAndSample(vtkImageMandelbrotSource *source)
{
  int idx;

  for (idx = 0; idx < 4; ++idx)
    {
    this->OriginCX[idx] = source->OriginCX[idx];
    this->SampleCX[idx] = source->SampleCX[idx];
    }

  this->Modified();
}
//----------------------------------------------------------------------------
void vtkImageMandelbrotSource::ExecuteData(vtkDataObject *output)
{
  vtkImageData *data = this->AllocateOutputData(output);
  int *ext, a0, a1, a2;
  float *ptr;
  int min0, max0;
  int idx0, idx1, idx2;
  int inc0, inc1, inc2;
  double *origin, *sample;
  double p[4];
  unsigned long count = 0;
  unsigned long target;

  // Copy origin into pixel
  for (idx0 = 0; idx0 < 4; ++idx0)
    {
    p[idx0] = this->OriginCX[idx0];
    }

  ext = data->GetUpdateExtent();
  ptr = (float *)(data->GetScalarPointerForExtent(ext));

  vtkDebugMacro("Generating Extent: " << ext[0] << " -> " << ext[1] << ", "
                << ext[2] << " -> " << ext[3]);

  // Get min and max of axis 0 because it is the innermost loop.
  min0 = ext[0];
  max0 = ext[1];
  data->GetContinuousIncrements(ext, inc0, inc1, inc2);

  target = (unsigned long)((ext[5]-ext[4]+1)*(ext[3]-ext[2]+1)/50.0);
  target++;

  a0 = this->ProjectionAxes[0];
  a1 = this->ProjectionAxes[1];
  a2 = this->ProjectionAxes[2];
  origin = this->OriginCX;
  sample = this->SampleCX;

  if (a0<0 || a1<0 || a2<0 || a0>3 || a1>3 || a2>3)
    {
    vtkErrorMacro("Bad projection axis");
    return;
    }
  for (idx2 = ext[4]; idx2 <= ext[5]; ++idx2)
    {
    p[a2] = (double)(origin[a2]) + (double)(idx2)*(sample[a2]);
    for (idx1 = ext[2]; !this->AbortExecute && idx1 <= ext[3]; ++idx1)
      {
      if (!(count%target))
        {
        this->UpdateProgress(count/(50.0*target));
        }
      count++;
      p[a1] = (double)(origin[a1]) + (double)(idx1)*(sample[a1]);
      for (idx0 = min0; idx0 <= max0; ++idx0)
        {
        p[a0] = (double)(origin[a0]) + (double)(idx0)*(sample[a0]);

        *ptr = (float)(this->EvaluateSet(p));

        ++ptr;
        // inc0 is 0
        }
      ptr += inc1;
      }
    ptr += inc2;
    }

  // Name the array appropriately.
  data->GetPointData()->GetScalars()->SetName("Iterations");
}

//----------------------------------------------------------------------------
float vtkImageMandelbrotSource::EvaluateSet(double p[4])
{
  unsigned short count = 0;
  double v0, v1;
  double cReal, cImag, zReal, zImag;
  double zReal2, zImag2;

  cReal = p[0];
  cImag = p[1];
  zReal = p[2];
  zImag = p[3];

  zReal2 = zReal * zReal;
  zImag2 = zImag * zImag;
  v0 = 0.0;
  v1 = (zReal2 + zImag2);
  while ( v1 < 4.0 && count < this->MaximumNumberOfIterations)
    {
    zImag = 2.0 * zReal * zImag + cImag;
    zReal = zReal2 - zImag2 + cReal;
    zReal2 = zReal * zReal;
    zImag2 = zImag * zImag;
    ++count;
    v0 = v1;
    v1 = (zReal2 + zImag2);
    }

  if (count == this->MaximumNumberOfIterations)
    {
    return (float)count;
    }

  return (float)count + (4.0 - v0)/(v1 - v0);
}

<|endoftext|>